111
This commit is contained in:
@@ -11,9 +11,9 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 候选人在入职任务中提交的固定人员基础信息。
|
||||
/// 候选人在入职任务中提交的《入职登记表》标准员工档案信息。
|
||||
/// </summary>
|
||||
[SugarTable("ob_task_employee_info", TableDescription = "候选人提交的固定基础信息")]
|
||||
[SugarTable("ob_task_employee_info", TableDescription = "候选人填写的入职登记表")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class ObTaskEmployeeInfo : BaseEntity
|
||||
{
|
||||
@@ -23,45 +23,57 @@ public class ObTaskEmployeeInfo : BaseEntity
|
||||
public long TaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 员工编号。
|
||||
/// 员工编号(选填/人事分配)。
|
||||
/// </summary>
|
||||
public string EmployeeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内部人员编号。
|
||||
/// </summary>
|
||||
public string InternalNo { get; set; }
|
||||
|
||||
// ==================== 1. 基本个人信息 ====================
|
||||
/// <summary>
|
||||
/// 员工姓名。
|
||||
/// </summary>
|
||||
public string EmployeeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属部门名称。
|
||||
/// </summary>
|
||||
public string DepartmentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别。
|
||||
/// </summary>
|
||||
public string Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号码。
|
||||
/// 民族。
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
public string Nation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证号码。
|
||||
/// 出生年月日。
|
||||
/// </summary>
|
||||
public string IdCardNumber { get; set; }
|
||||
public string Birthday { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 毕业院校。
|
||||
/// 户籍所在地。
|
||||
/// </summary>
|
||||
public string College { get; set; }
|
||||
public string RegisteredResidence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身高 (cm)。
|
||||
/// </summary>
|
||||
public string Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 体重 (kg)。
|
||||
/// </summary>
|
||||
public string Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 健康状况。
|
||||
/// </summary>
|
||||
public string HealthCondition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 婚育情况。
|
||||
/// </summary>
|
||||
public string MaritalStatus { get; set; }
|
||||
|
||||
// ==================== 2. 学历与资质 ====================
|
||||
/// <summary>
|
||||
/// 最高学历。
|
||||
/// </summary>
|
||||
@@ -73,82 +85,125 @@ public class ObTaskEmployeeInfo : BaseEntity
|
||||
public string Major { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期。
|
||||
/// 毕业院校。
|
||||
/// </summary>
|
||||
public DateTime? BirthDate { get; set; }
|
||||
public string GraduatedSchool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 户籍所在地。
|
||||
/// 职业资格。
|
||||
/// </summary>
|
||||
public string RegisteredResidence { get; set; }
|
||||
public string VocationalQualification { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 民族。
|
||||
/// 资格等级。
|
||||
/// </summary>
|
||||
public string Nation { get; set; }
|
||||
public string QualificationLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 现居住或联系地址。
|
||||
/// 有何技术特长。
|
||||
/// </summary>
|
||||
public string ContactAddress { get; set; }
|
||||
public string TechnicalSpecialty { get; set; }
|
||||
|
||||
// ==================== 3. 联系方式与薪酬账户 ====================
|
||||
/// <summary>
|
||||
/// 联系电话/手机号。
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入职日期。
|
||||
/// 电子邮箱。
|
||||
/// </summary>
|
||||
public DateTime? EntryDate { get; set; }
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合同开始日期。
|
||||
/// 身份证号码。
|
||||
/// </summary>
|
||||
public DateTime? ContractStartDate { get; set; }
|
||||
public string IdCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合同结束日期。
|
||||
/// 暂住地址 / 现居住地址。
|
||||
/// </summary>
|
||||
public DateTime? ContractEndDate { get; set; }
|
||||
public string CurrentAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 试用期开始日期。
|
||||
/// 房东联系方式。
|
||||
/// </summary>
|
||||
public DateTime? ProbationStartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 试用期结束日期。
|
||||
/// </summary>
|
||||
public DateTime? ProbationEndDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 转正日期。
|
||||
/// </summary>
|
||||
public DateTime? RegularizationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 社保缴纳公司。
|
||||
/// </summary>
|
||||
public string SocialInsuranceCompany { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合同性质。
|
||||
/// </summary>
|
||||
public string ContractNature { get; set; }
|
||||
public string LandlordContact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工资银行卡号。
|
||||
/// </summary>
|
||||
public string BankCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 银行卡开户名。
|
||||
/// </summary>
|
||||
public string BankAccountName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开户银行名称。
|
||||
/// </summary>
|
||||
public string BankName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务备注。
|
||||
/// 银行卡开户人姓名。
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
public string BankAccountName { get; set; }
|
||||
|
||||
// ==================== 4. 紧急联系人 ====================
|
||||
/// <summary>
|
||||
/// 紧急联系人姓名。
|
||||
/// </summary>
|
||||
public string EmergencyContact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人电话。
|
||||
/// </summary>
|
||||
public string EmergencyPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 紧急联系人联系地址。
|
||||
/// </summary>
|
||||
public string EmergencyAddress { get; set; }
|
||||
|
||||
// ==================== 5. 动态多条经历(JSON 存储) ====================
|
||||
/// <summary>
|
||||
/// 教育学习经历 JSON 列表: [ { timeRange, location, content, result } ]
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string EducationHistoryJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主要工作经历 JSON 列表: [ { timeRange, companyName, salary, position, leaveReason } ]
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string WorkHistoryJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 家庭成员 JSON 列表: [ { name, relationship, age, company, phone } ]
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string FamilyMembersJson { get; set; }
|
||||
|
||||
// ==================== 6. 入职情况与说明 ====================
|
||||
/// <summary>
|
||||
/// 入职部门。
|
||||
/// </summary>
|
||||
public string OnboardingDepartment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入职时间。
|
||||
/// </summary>
|
||||
public string OnboardingDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入职岗位。
|
||||
/// </summary>
|
||||
public string OnboardingPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 其他说明。
|
||||
/// </summary>
|
||||
public string OtherRemarks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 员工补充自定义变量键值 JSON: { "VariableName": "Value" }
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string CustomVariablesJson { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 全局合同变量字典定义表。
|
||||
/// 包含标准入职登记表变量、人事合同变量及企业自定义变量。
|
||||
/// </summary>
|
||||
[SugarTable("ob_variable_definition", TableDescription = "合同变量字典定义")]
|
||||
[Tenant(SqlSugarConst.DB_DEFAULT)]
|
||||
public class ObVariableDefinition : BaseEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 变量全编码,如 employee.EmployeeName, hr.BaseSalary, company.CompanyName, system.TaskNo。
|
||||
/// </summary>
|
||||
public string VariableCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 变量中文显示名称,如“员工姓名”、“基本工资”。
|
||||
/// </summary>
|
||||
public string VariableName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 变量作用域分类:employee(员工变量), hr(人事参数), company(公司变量), system(系统变量)。
|
||||
/// </summary>
|
||||
public string VariableCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据类型:string, number, date, multiline。
|
||||
/// </summary>
|
||||
public string DataType { get; set; } = "string";
|
||||
|
||||
/// <summary>
|
||||
/// 默认值或占位提示。
|
||||
/// </summary>
|
||||
public string DefaultValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为入职登记表内置字段(内置字段不可删,且第1步自动收集)。
|
||||
/// </summary>
|
||||
public bool IsBuiltIn { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否必填。
|
||||
/// </summary>
|
||||
public bool Required { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 排序码。
|
||||
/// </summary>
|
||||
public int SortCode { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 变量说明/备注。
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
@@ -44,14 +44,25 @@ public class OnboardingAuditService : IOnboardingAuditService
|
||||
throw Oops.Bah("该身份证号或手机号已存在正式员工");
|
||||
}
|
||||
|
||||
var extraValues = await _db.Queryable<ObTaskFormValue>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync();
|
||||
var employee = employeeInfo.Adapt<ObEmployee>();
|
||||
employee.Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId();
|
||||
employee.CompanyId = task.CompanyId;
|
||||
employee.PositionId = task.PositionId;
|
||||
employee.ExtraInfoJson = global::System.Text.Json.JsonSerializer.Serialize(extraValues);
|
||||
employee.DepartmentName = employeeInfo.OnboardingDepartment;
|
||||
employee.College = employeeInfo.GraduatedSchool;
|
||||
employee.BirthDate = ParseDate(employeeInfo.Birthday);
|
||||
employee.ContactAddress = employeeInfo.CurrentAddress;
|
||||
employee.EntryDate = ParseDate(employeeInfo.OnboardingDate);
|
||||
employee.Remark = employeeInfo.OtherRemarks;
|
||||
employee.ExtraInfoJson = global::System.Text.Json.JsonSerializer.Serialize(employeeInfo);
|
||||
employee.Status = CommonStatusConst.ENABLE;
|
||||
employee.CreateTime = DateTime.Now;
|
||||
employee.CreateUserId = UserManager.UserId;
|
||||
employee.CreateUser = UserManager.Name;
|
||||
employee.UpdateTime = null;
|
||||
employee.UpdateUserId = null;
|
||||
employee.UpdateUser = null;
|
||||
employee.IsDelete = false;
|
||||
|
||||
// 员工档案、任务状态和审核记录必须同时成功,避免出现“已通过但没有员工档案”的中间状态。
|
||||
await _db.Ado.BeginTranAsync();
|
||||
@@ -124,6 +135,16 @@ public class OnboardingAuditService : IOnboardingAuditService
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将登记表中的日期文本转换为正式员工档案日期。
|
||||
/// </summary>
|
||||
private static DateTime? ParseDate(string value)
|
||||
{
|
||||
return DateTime.TryParse(value, out var result)
|
||||
? result.Date
|
||||
: null;
|
||||
}
|
||||
|
||||
private Task WriteAudit(ObOnboardingTask task, string action, string opinion)
|
||||
{
|
||||
return _db.Insertable(new ObTaskAudit
|
||||
|
||||
+23
-8
@@ -26,12 +26,8 @@ public class OnboardingContractSnapshotService : IOnboardingContractSnapshotServ
|
||||
?? throw Oops.Bah("入职公司不存在");
|
||||
employeeInfo ??= await _db.Queryable<ObTaskEmployeeInfo>()
|
||||
.FirstAsync(item => item.TaskId == taskId);
|
||||
var dynamicValues = await _db.Queryable<ObTaskFormValue>()
|
||||
.Where(item => item.TaskId == taskId)
|
||||
.ToListAsync();
|
||||
var dynamicValueMap = dynamicValues
|
||||
.GroupBy(item => item.FieldCode, StringComparer.OrdinalIgnoreCase)
|
||||
.ToDictionary(group => group.Key, group => group.Last().FieldValue, StringComparer.OrdinalIgnoreCase);
|
||||
// 员工补充合同变量统一从 CustomVariablesJson 读取,不再访问已移除的旧动态字段表。
|
||||
var dynamicValueMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
var contracts = await _db.Queryable<ObTaskContract>()
|
||||
.Where(item => item.TaskId == taskId)
|
||||
.ToListAsync();
|
||||
@@ -110,6 +106,23 @@ public class OnboardingContractSnapshotService : IOnboardingContractSnapshotServ
|
||||
var fixedValue = GetPropertyValue(employeeInfo, ResolveEmployeeField(sourceField), definition.FormatRule);
|
||||
if (!string.IsNullOrWhiteSpace(fixedValue))
|
||||
return fixedValue;
|
||||
|
||||
// 检查员工自定义补充变量 JSON
|
||||
if (!string.IsNullOrWhiteSpace(employeeInfo?.CustomVariablesJson))
|
||||
{
|
||||
try
|
||||
{
|
||||
using var doc = global::System.Text.Json.JsonDocument.Parse(employeeInfo.CustomVariablesJson);
|
||||
if (doc.RootElement.TryGetProperty(sourceField, out var prop)
|
||||
|| doc.RootElement.TryGetProperty(definition.VariableCode, out prop))
|
||||
{
|
||||
var str = prop.GetString();
|
||||
if (!string.IsNullOrWhiteSpace(str)) return str;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
return dynamicValues.TryGetValue(sourceField, out var dynamicValue)
|
||||
? dynamicValue
|
||||
: definition.DefaultValue;
|
||||
@@ -184,8 +197,10 @@ public class OnboardingContractSnapshotService : IOnboardingContractSnapshotServ
|
||||
"LEGALNAME" or "LEGAL_NAME" or "COMPANYLEGALNAME" => nameof(ObCompany.LegalName),
|
||||
"UNIFIEDSOCIALCREDITCODE" or "UNIFIED_SOCIAL_CREDIT_CODE" => nameof(ObCompany.UnifiedSocialCreditCode),
|
||||
"LEGALREPRESENTATIVE" or "LEGAL_REPRESENTATIVE" => nameof(ObCompany.LegalRepresentative),
|
||||
"REGISTEREDADDRESS" or "REGISTERED_ADDRESS" => nameof(ObCompany.RegisteredAddress),
|
||||
"CONTACTPHONE" or "CONTACT_PHONE" => nameof(ObCompany.ContactPhone),
|
||||
"ADDRESS" or "COMPANYADDRESS" or "COMPANY_ADDRESS"
|
||||
or "REGISTEREDADDRESS" or "REGISTERED_ADDRESS" => nameof(ObCompany.RegisteredAddress),
|
||||
"PHONE" or "COMPANYPHONE" or "COMPANY_PHONE"
|
||||
or "CONTACTPHONE" or "CONTACT_PHONE" => nameof(ObCompany.ContactPhone),
|
||||
_ => sourceField
|
||||
};
|
||||
}
|
||||
|
||||
+24
-6
@@ -179,6 +179,16 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
await sourceStream.CopyToAsync(sourceBytes);
|
||||
var bytes = sourceBytes.ToArray();
|
||||
var variableCodes = DocxTemplateProcessor.ExtractVariableCodes(bytes);
|
||||
|
||||
// 严格比对变量字典库,防止手误和非法占位符
|
||||
var dictList = await Context.Queryable<ObVariableDefinition>().ToListAsync();
|
||||
var dictMap = dictList.ToDictionary(it => it.VariableCode, it => it, StringComparer.OrdinalIgnoreCase);
|
||||
var undefinedCodes = variableCodes.Where(code => !dictMap.ContainsKey(code)).ToList();
|
||||
if (undefinedCodes.Count > 0)
|
||||
{
|
||||
throw Oops.Bah($"DOCX 模板包含未在字典库中注册的占位符:{string.Join(",", undefinedCodes)}。请检查拼写或先在【变量字典】中添加该变量。");
|
||||
}
|
||||
|
||||
var versionId = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId();
|
||||
var version = input.Adapt<ObContractTemplateVersion>();
|
||||
version.Id = versionId;
|
||||
@@ -186,7 +196,12 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
version.FileHash = string.IsNullOrWhiteSpace(input.FileHash)
|
||||
? Convert.ToHexString(global::System.Security.Cryptography.SHA256.HashData(bytes))
|
||||
: input.FileHash;
|
||||
var variables = variableCodes.Select((code, index) => BuildDetectedVariable(versionId, code, index)).ToList();
|
||||
|
||||
var variables = variableCodes.Select((code, index) =>
|
||||
{
|
||||
var def = dictMap.TryGetValue(code, out var d) ? d : null;
|
||||
return BuildDetectedVariable(versionId, code, def, index);
|
||||
}).ToList();
|
||||
|
||||
await Context.Ado.BeginTranAsync();
|
||||
try
|
||||
@@ -263,7 +278,7 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
await Context.Updateable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
private static ObTemplateVariable BuildDetectedVariable(long versionId, string code, int index)
|
||||
private static ObTemplateVariable BuildDetectedVariable(long versionId, string code, ObVariableDefinition def, int index)
|
||||
{
|
||||
var separatorIndex = code.IndexOf('.');
|
||||
var prefix = separatorIndex > 0 ? code[..separatorIndex].ToLowerInvariant() : string.Empty;
|
||||
@@ -277,21 +292,24 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
_ => ContractVariableType.Unresolved
|
||||
};
|
||||
|
||||
var varName = def != null && !string.IsNullOrWhiteSpace(def.VariableName) ? def.VariableName : sourceField;
|
||||
var dataType = def != null && !string.IsNullOrWhiteSpace(def.DataType) ? def.DataType : InferDataType(sourceField);
|
||||
|
||||
return new ObTemplateVariable
|
||||
{
|
||||
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
|
||||
TemplateVersionId = versionId,
|
||||
VariableCode = code,
|
||||
VariableName = sourceField,
|
||||
VariableName = varName,
|
||||
VariableType = variableType,
|
||||
DataType = InferDataType(sourceField),
|
||||
DataType = dataType,
|
||||
EmployeeField = variableType is ContractVariableType.Employee or ContractVariableType.Company
|
||||
? sourceField
|
||||
: null,
|
||||
Required = true,
|
||||
Required = def?.Required ?? true,
|
||||
HrEditable = variableType == ContractVariableType.Contract,
|
||||
SortCode = (index + 1) * 10,
|
||||
Remark = variableType == ContractVariableType.Unresolved ? "导入时未识别变量来源,请管理员确认" : null
|
||||
Remark = def?.Remark
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -83,10 +83,8 @@ public class OnboardingTaskLifecycleService : IOnboardingTaskLifecycleService
|
||||
|
||||
await _db.Deleteable<ObTaskContract>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskLink>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskFormRequirement>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskMaterialRequirement>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskMaterial>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskFormValue>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskEmployeeInfo>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObTaskAudit>().Where(x => x.TaskId == task.Id).ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObOnboardingTask>().In(task.Id).ExecuteCommandAsync();
|
||||
|
||||
+3
-87
@@ -75,10 +75,7 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
.Where(item => item.OnboardingTemplateId == template.Id)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync(),
|
||||
FormFields = await _db.Queryable<ObOnboardingTemplateFormField>()
|
||||
.Where(item => item.OnboardingTemplateId == template.Id)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync(),
|
||||
FormFields = new List<ObOnboardingTemplateFormField>(),
|
||||
Materials = await _db.Queryable<ObOnboardingTemplateMaterial>()
|
||||
.Where(item => item.OnboardingTemplateId == template.Id)
|
||||
.OrderBy(item => item.SortCode)
|
||||
@@ -246,49 +243,6 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
{
|
||||
if (versions.Any(item => item.VersionStatus != ContractTemplateVersionStatus.Enabled))
|
||||
throw Oops.Bah("启用入职模板前,请先启用全部合同版本");
|
||||
|
||||
var variables = await _db.Queryable<ObTemplateVariable>()
|
||||
.Where(item => versionIds.Contains(item.TemplateVersionId))
|
||||
.ToListAsync();
|
||||
var validTypes = new[]
|
||||
{
|
||||
ContractVariableType.Employee,
|
||||
ContractVariableType.Company,
|
||||
ContractVariableType.Contract,
|
||||
ContractVariableType.System
|
||||
};
|
||||
if (variables.Any(item => !validTypes.Contains(item.VariableType)))
|
||||
throw Oops.Bah("合同中仍有未确认来源的变量,请先完成变量映射");
|
||||
}
|
||||
|
||||
var fieldIds = input.FormFields.Select(item => item.FieldId).ToList();
|
||||
var enabledFields = fieldIds.Count == 0
|
||||
? new List<ObFormField>()
|
||||
: await _db.Queryable<ObFormField>()
|
||||
.Where(item => fieldIds.Contains(item.Id) && item.Status == "enable")
|
||||
.ToListAsync();
|
||||
if (enabledFields.Count != fieldIds.Count)
|
||||
throw Oops.Bah("存在未启用或不存在的动态补充字段");
|
||||
|
||||
if (input.Status == "enable")
|
||||
{
|
||||
var variables = await _db.Queryable<ObTemplateVariable>()
|
||||
.Where(item => versionIds.Contains(item.TemplateVersionId)
|
||||
&& item.VariableType == ContractVariableType.Employee)
|
||||
.ToListAsync();
|
||||
var availableFields = new HashSet<string>(
|
||||
typeof(ObTaskEmployeeInfo).GetProperties().Select(property => property.Name),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var fieldCode in enabledFields.Select(item => item.FieldCode))
|
||||
availableFields.Add(fieldCode);
|
||||
|
||||
var missingMapping = variables.FirstOrDefault(variable =>
|
||||
!availableFields.Contains(ResolveEmployeeVariableField(variable)));
|
||||
if (missingMapping != null)
|
||||
{
|
||||
throw Oops.Bah(
|
||||
$"合同员工变量“{missingMapping.VariableCode}”没有对应的固定字段或模板补充字段,请先完成字段映射");
|
||||
}
|
||||
}
|
||||
|
||||
var materialIds = input.Materials.Select(item => item.MaterialTypeId).ToList();
|
||||
@@ -301,25 +255,6 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
}
|
||||
}
|
||||
|
||||
private static string ResolveEmployeeVariableField(ObTemplateVariable variable)
|
||||
{
|
||||
var sourceField = variable.EmployeeField;
|
||||
if (string.IsNullOrWhiteSpace(sourceField))
|
||||
{
|
||||
var separatorIndex = variable.VariableCode?.IndexOf('.') ?? -1;
|
||||
sourceField = separatorIndex >= 0
|
||||
? variable.VariableCode[(separatorIndex + 1)..]
|
||||
: variable.VariableCode;
|
||||
}
|
||||
|
||||
return sourceField?.ToUpperInvariant() switch
|
||||
{
|
||||
"FULLNAME" or "FULL_NAME" or "NAME" => nameof(ObTaskEmployeeInfo.EmployeeName),
|
||||
"MOBILE" or "MOBILEPHONE" or "MOBILE_PHONE" => nameof(ObTaskEmployeeInfo.Phone),
|
||||
"IDNUMBER" or "ID_NUMBER" or "IDENTITYNUMBER" => nameof(ObTaskEmployeeInfo.IdCardNumber),
|
||||
_ => sourceField
|
||||
};
|
||||
}
|
||||
private async Task InsertRelations(long templateId, OnboardingTemplateSaveInput input)
|
||||
{
|
||||
var positions = input.PositionIds.Select(positionId => new ObOnboardingTemplatePosition
|
||||
@@ -342,20 +277,7 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
}).ToList();
|
||||
await _db.Insertable(contracts).ExecuteCommandAsync();
|
||||
|
||||
if (input.FormFields.Count > 0)
|
||||
{
|
||||
var fields = input.FormFields.Select(item => new ObOnboardingTemplateFormField
|
||||
{
|
||||
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
|
||||
OnboardingTemplateId = templateId,
|
||||
FieldId = item.FieldId,
|
||||
Required = item.Required,
|
||||
SortCode = item.SortCode
|
||||
}).ToList();
|
||||
await _db.Insertable(fields).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
if (input.Materials.Count > 0)
|
||||
if (input.Materials != null && input.Materials.Count > 0)
|
||||
{
|
||||
var materials = input.Materials.Select(item => new ObOnboardingTemplateMaterial
|
||||
{
|
||||
@@ -377,9 +299,6 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
await _db.Deleteable<ObOnboardingTemplateContract>()
|
||||
.Where(item => item.OnboardingTemplateId == templateId)
|
||||
.ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObOnboardingTemplateFormField>()
|
||||
.Where(item => item.OnboardingTemplateId == templateId)
|
||||
.ExecuteCommandAsync();
|
||||
await _db.Deleteable<ObOnboardingTemplateMaterial>()
|
||||
.Where(item => item.OnboardingTemplateId == templateId)
|
||||
.ExecuteCommandAsync();
|
||||
@@ -405,9 +324,6 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
var contracts = await _db.Queryable<ObOnboardingTemplateContract>()
|
||||
.Where(item => templateIds.Contains(item.OnboardingTemplateId))
|
||||
.ToListAsync();
|
||||
var fields = await _db.Queryable<ObOnboardingTemplateFormField>()
|
||||
.Where(item => templateIds.Contains(item.OnboardingTemplateId))
|
||||
.ToListAsync();
|
||||
var materials = await _db.Queryable<ObOnboardingTemplateMaterial>()
|
||||
.Where(item => templateIds.Contains(item.OnboardingTemplateId))
|
||||
.ToListAsync();
|
||||
@@ -432,7 +348,7 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
.Where(name => !string.IsNullOrWhiteSpace(name))
|
||||
.ToList(),
|
||||
ContractCount = contracts.Count(item => item.OnboardingTemplateId == template.Id),
|
||||
FormFieldCount = fields.Count(item => item.OnboardingTemplateId == template.Id),
|
||||
FormFieldCount = 0,
|
||||
MaterialCount = materials.Count(item => item.OnboardingTemplateId == template.Id)
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
+17
@@ -55,6 +55,23 @@ public class OnboardingSaveMaterialInput
|
||||
public long FileId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除员工在当前可编辑任务中上传的一条材料。
|
||||
/// </summary>
|
||||
public class OnboardingDeleteMaterialInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 员工填写链接中的明文 Token。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.DataAnnotations.Required]
|
||||
public string Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务材料记录 Id。
|
||||
/// </summary>
|
||||
public long TaskMaterialId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 员工确认阅读合同参数。
|
||||
/// </summary>
|
||||
|
||||
+9
@@ -9,18 +9,27 @@ public interface IOnboardingPublicSubmissionService : ITransient
|
||||
/// 保存候选人填写的动态字段值。
|
||||
/// </summary>
|
||||
Task SaveDynamicValues(OnboardingSaveDynamicValuesInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 关联候选人已经上传的系统文件与材料类型。
|
||||
/// </summary>
|
||||
Task SaveMaterial(OnboardingSaveMaterialInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 删除可编辑任务中的一条已上传材料关联。
|
||||
/// </summary>
|
||||
Task DeleteMaterial(OnboardingDeleteMaterialInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 记录候选人已阅读并确认指定任务合同。
|
||||
/// </summary>
|
||||
Task ConfirmContract(OnboardingConfirmContractInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 校验全部必填资料后提交入职任务进入审核。
|
||||
/// </summary>
|
||||
Task Submit(OnboardingSubmitInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 在保存文件前校验材料适用范围、扩展名、大小和数量。
|
||||
/// </summary>
|
||||
|
||||
+25
-53
@@ -19,37 +19,8 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ
|
||||
/// </summary>
|
||||
public async Task SaveDynamicValues(OnboardingSaveDynamicValuesInput input)
|
||||
{
|
||||
var task = await GetEditableTask(input.Token);
|
||||
var requirements = await GetFormRequirements(task.Id);
|
||||
var fieldIds = input.Values.Select(item => item.FieldId).Distinct().ToList();
|
||||
var hasInapplicableField = fieldIds.Any(id => requirements.All(item => item.FieldId != id));
|
||||
if (hasInapplicableField)
|
||||
throw Oops.Bah("填写字段不属于当前入职模板");
|
||||
|
||||
foreach (var value in input.Values)
|
||||
{
|
||||
var requirement = requirements.FirstOrDefault(item => item.FieldId == value.FieldId)
|
||||
?? throw Oops.Bah("动态补充字段不存在");
|
||||
var old = await _db.Queryable<ObTaskFormValue>()
|
||||
.FirstAsync(item => item.TaskId == task.Id && item.FieldId == requirement.FieldId);
|
||||
var row = new ObTaskFormValue
|
||||
{
|
||||
Id = old?.Id ?? global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
|
||||
TaskId = task.Id,
|
||||
FieldId = requirement.FieldId,
|
||||
FieldCode = requirement.FieldCode,
|
||||
FieldName = requirement.FieldName,
|
||||
FieldValue = value.FieldValue,
|
||||
SubmitRound = task.SubmitCount + 1
|
||||
};
|
||||
|
||||
if (old == null)
|
||||
await _db.Insertable(row).ExecuteCommandAsync();
|
||||
else
|
||||
await _db.Updateable(row).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
await _snapshotService.Build(task.Id, invalidateGeneratedPreview: true);
|
||||
await GetEditableTask(input.Token);
|
||||
throw Oops.Bah("新版入职登记表不再使用旧动态字段接口,请通过员工基础信息接口保存补充变量");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -96,6 +67,25 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ
|
||||
}).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 任务仍可编辑时删除一条已上传材料。
|
||||
/// </summary>
|
||||
public async Task DeleteMaterial(
|
||||
OnboardingDeleteMaterialInput input)
|
||||
{
|
||||
var task = await GetEditableTask(input.Token);
|
||||
var material = await _db.Queryable<ObTaskMaterial>()
|
||||
.FirstAsync(item =>
|
||||
item.Id == input.TaskMaterialId
|
||||
&& item.TaskId == task.Id);
|
||||
if (material == null)
|
||||
throw Oops.Bah("上传材料不存在");
|
||||
|
||||
await _db.Deleteable<ObTaskMaterial>()
|
||||
.In(material.Id)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录候选人已经查看并确认动态生成的合同。
|
||||
/// </summary>
|
||||
@@ -124,24 +114,14 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ
|
||||
var basicInfoIncomplete = info == null
|
||||
|| string.IsNullOrWhiteSpace(info.EmployeeName)
|
||||
|| string.IsNullOrWhiteSpace(info.Phone)
|
||||
|| string.IsNullOrWhiteSpace(info.IdCardNumber);
|
||||
|| string.IsNullOrWhiteSpace(info.IdCardNumber)
|
||||
|| string.IsNullOrWhiteSpace(info.BankCardNumber)
|
||||
|| string.IsNullOrWhiteSpace(info.BankName);
|
||||
if (basicInfoIncomplete)
|
||||
throw Oops.Bah("请先完整填写基本信息");
|
||||
|
||||
await _snapshotService.Build(task.Id, info);
|
||||
|
||||
var requiredFields = (await GetFormRequirements(task.Id))
|
||||
.Where(item => item.Required)
|
||||
.Select(item => item.FieldId)
|
||||
.ToList();
|
||||
var values = await _db.Queryable<ObTaskFormValue>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync();
|
||||
var hasMissingRequiredField = requiredFields.Any(
|
||||
id => values.All(item => item.FieldId != id || string.IsNullOrWhiteSpace(item.FieldValue)));
|
||||
if (hasMissingRequiredField)
|
||||
throw Oops.Bah("仍有必填补充信息未填写");
|
||||
|
||||
var requiredMaterials = (await GetMaterialRequirements(task.Id))
|
||||
.Where(item => item.Required)
|
||||
.Select(item => item.MaterialTypeId)
|
||||
@@ -174,7 +154,7 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ
|
||||
AuditRound = task.SubmitCount,
|
||||
AuditAction = OnboardingAuditAction.Submit,
|
||||
AuditOpinion = "员工提交入职资料",
|
||||
SnapshotJson = global::System.Text.Json.JsonSerializer.Serialize(new { info, values, materials }),
|
||||
SnapshotJson = global::System.Text.Json.JsonSerializer.Serialize(new { info, materials }),
|
||||
AuditedAt = DateTime.Now
|
||||
}).ExecuteCommandAsync();
|
||||
}
|
||||
@@ -235,14 +215,6 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ
|
||||
throw Oops.Bah($"合同“{missing.contract.ContractName}”的必填变量“{missing.definition.VariableName}”尚未填写");
|
||||
}
|
||||
|
||||
private Task<List<ObTaskFormRequirement>> GetFormRequirements(long taskId)
|
||||
{
|
||||
return _db.Queryable<ObTaskFormRequirement>()
|
||||
.Where(item => item.TaskId == taskId)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
private Task<List<ObTaskMaterialRequirement>> GetMaterialRequirements(long taskId)
|
||||
{
|
||||
return _db.Queryable<ObTaskMaterialRequirement>()
|
||||
|
||||
+47
-22
@@ -19,7 +19,7 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过有效 Token 获取任务创建时冻结的字段、材料和合同信息。
|
||||
/// 通过有效 Token 获取任务创建时冻结的材料、合同和新版入职登记表信息。
|
||||
/// </summary>
|
||||
public async Task<OnboardingTaskPublicDetailOutput> Detail(OnboardingTaskPublicAccessInput input)
|
||||
{
|
||||
@@ -30,39 +30,49 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
||||
link.AccessCount++;
|
||||
link.LastAccessedAt = DateTime.Now;
|
||||
await _db.Updateable(link).ExecuteCommandAsync();
|
||||
|
||||
var formRequirements = await _db.Queryable<ObTaskFormRequirement>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync();
|
||||
var materialRequirements = await _db.Queryable<ObTaskMaterialRequirement>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync();
|
||||
|
||||
var contracts = await _db.Queryable<ObTaskContract>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync();
|
||||
var templateVersionIds = contracts
|
||||
.Select(item => item.TemplateVersionId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
var contractVariables = new List<OnboardingPublicContractVariableOutput>();
|
||||
if (templateVersionIds.Count > 0)
|
||||
{
|
||||
var employeeVariables = await _db.Queryable<ObTemplateVariable>()
|
||||
.Where(item => templateVersionIds.Contains(item.TemplateVersionId)
|
||||
&& item.VariableType == ContractVariableType.Employee)
|
||||
.OrderBy(item => item.SortCode)
|
||||
.ToListAsync();
|
||||
contractVariables = employeeVariables.Select(item => new OnboardingPublicContractVariableOutput
|
||||
{
|
||||
VariableCode = item.VariableCode,
|
||||
VariableName = item.VariableName,
|
||||
VariableType = item.VariableType,
|
||||
DataType = item.DataType,
|
||||
DefaultValue = item.DefaultValue,
|
||||
OptionsJson = item.OptionsJson,
|
||||
Required = item.Required
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
return new OnboardingTaskPublicDetailOutput
|
||||
{
|
||||
Task = task,
|
||||
EmployeeInfo = await _db.Queryable<ObTaskEmployeeInfo>()
|
||||
.FirstAsync(item => item.TaskId == task.Id),
|
||||
Contracts = await _db.Queryable<ObTaskContract>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
DynamicValues = await _db.Queryable<ObTaskFormValue>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
Contracts = contracts,
|
||||
DynamicValues = new List<ObTaskFormValue>(),
|
||||
Materials = await _db.Queryable<ObTaskMaterial>()
|
||||
.Where(item => item.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
FormFields = formRequirements.Select(requirement => new OnboardingPublicFormFieldOutput
|
||||
{
|
||||
FieldId = requirement.FieldId,
|
||||
FieldCode = requirement.FieldCode,
|
||||
FieldName = requirement.FieldName,
|
||||
DataType = requirement.DataType,
|
||||
OptionsJson = requirement.OptionsJson,
|
||||
Required = requirement.Required
|
||||
}).ToList(),
|
||||
FormFields = new List<OnboardingPublicFormFieldOutput>(),
|
||||
MaterialRequirements = materialRequirements.Select(requirement => new OnboardingPublicMaterialOutput
|
||||
{
|
||||
MaterialTypeId = requirement.MaterialTypeId,
|
||||
@@ -70,7 +80,8 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
||||
AllowedExtensions = requirement.AllowedExtensions,
|
||||
MaxFileCount = requirement.MaxFileCount,
|
||||
Required = requirement.Required
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
ContractVariables = contractVariables
|
||||
};
|
||||
}
|
||||
|
||||
@@ -92,15 +103,29 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
||||
.FirstAsync(item => item.TaskId == task.Id);
|
||||
var entity = input.Adapt<ObTaskEmployeeInfo>();
|
||||
entity.TaskId = task.Id;
|
||||
entity.IsDelete = false;
|
||||
|
||||
if (old == null)
|
||||
{
|
||||
entity.Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId();
|
||||
entity.Status = CommonStatusConst.ENABLE;
|
||||
entity.CreateTime = DateTime.Now;
|
||||
entity.CreateUserId = null;
|
||||
entity.CreateUser = null;
|
||||
await _db.Insertable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.Id = old.Id;
|
||||
entity.Status = old.Status;
|
||||
entity.CreateTime = old.CreateTime;
|
||||
entity.CreateUserId = old.CreateUserId;
|
||||
entity.CreateUser = old.CreateUser;
|
||||
entity.ExtJson = old.ExtJson;
|
||||
entity.IsDelete = old.IsDelete;
|
||||
entity.UpdateTime = DateTime.Now;
|
||||
entity.UpdateUserId = null;
|
||||
entity.UpdateUser = null;
|
||||
await _db.Updateable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -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}结束日期不能早于开始日期");
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
public interface IOnboardingVariableDefinitionService : ITransient
|
||||
{
|
||||
Task<SqlSugarPagedList<ObVariableDefinition>> Page(OnboardingVariableDefinitionPageInput input);
|
||||
Task<List<ObVariableDefinition>> ListAll();
|
||||
Task Add(OnboardingVariableDefinitionAddInput input);
|
||||
Task Edit(OnboardingVariableDefinitionEditInput input);
|
||||
Task Delete(BaseIdListInput input);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
public class OnboardingVariableDefinitionPageInput : BasePageInput
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public string VariableCategory { get; set; }
|
||||
}
|
||||
|
||||
public class OnboardingVariableDefinitionAddInput
|
||||
{
|
||||
[Required(ErrorMessage = "变量编码不能为空")]
|
||||
public string VariableCode { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "变量名称不能为空")]
|
||||
public string VariableName { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "变量分类不能为空")]
|
||||
public string VariableCategory { get; set; }
|
||||
|
||||
public string DataType { get; set; } = "string";
|
||||
public string DefaultValue { get; set; }
|
||||
public bool Required { get; set; }
|
||||
public int SortCode { get; set; } = 100;
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
|
||||
public class OnboardingVariableDefinitionEditInput : OnboardingVariableDefinitionAddInput
|
||||
{
|
||||
[IdNotNull(ErrorMessage = "Id不能为空")]
|
||||
public long Id { get; set; }
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
public class OnboardingVariableDefinitionService : IOnboardingVariableDefinitionService
|
||||
{
|
||||
private readonly SqlSugarScope _db;
|
||||
private static bool _initialized = false;
|
||||
private static readonly object _lock = new();
|
||||
|
||||
public OnboardingVariableDefinitionService()
|
||||
{
|
||||
_db = DbContext.DB;
|
||||
}
|
||||
|
||||
public async Task<SqlSugarPagedList<ObVariableDefinition>> Page(OnboardingVariableDefinitionPageInput input)
|
||||
{
|
||||
return await _db.Queryable<ObVariableDefinition>()
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), it => it.VariableCode.Contains(input.Keyword) || it.VariableName.Contains(input.Keyword))
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.VariableCategory), it => it.VariableCategory == input.VariableCategory)
|
||||
.OrderBy(it => it.SortCode)
|
||||
.OrderBy(it => it.Id)
|
||||
.ToPagedListAsync(input.PageNum, input.PageSize);
|
||||
}
|
||||
|
||||
public async Task<List<ObVariableDefinition>> ListAll()
|
||||
{
|
||||
return await _db.Queryable<ObVariableDefinition>()
|
||||
.OrderBy(it => it.SortCode)
|
||||
.OrderBy(it => it.Id)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task Add(OnboardingVariableDefinitionAddInput input)
|
||||
{
|
||||
var code = input.VariableCode.Trim();
|
||||
var exists = await _db.Queryable<ObVariableDefinition>().AnyAsync(it => it.VariableCode == code);
|
||||
if (exists)
|
||||
throw Oops.Bah($"变量编码“{code}”已存在");
|
||||
|
||||
var entity = input.Adapt<ObVariableDefinition>();
|
||||
entity.VariableCode = code;
|
||||
entity.IsBuiltIn = false;
|
||||
await _db.Insertable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public async Task Edit(OnboardingVariableDefinitionEditInput input)
|
||||
{
|
||||
var entity = await _db.Queryable<ObVariableDefinition>().InSingleAsync(input.Id)
|
||||
?? throw Oops.Bah("变量不存在");
|
||||
|
||||
entity.VariableName = input.VariableName;
|
||||
entity.DataType = input.DataType ?? "string";
|
||||
entity.DefaultValue = input.DefaultValue;
|
||||
entity.Required = input.Required;
|
||||
entity.SortCode = input.SortCode;
|
||||
entity.Remark = input.Remark;
|
||||
if (!entity.IsBuiltIn)
|
||||
{
|
||||
entity.VariableCategory = input.VariableCategory;
|
||||
}
|
||||
|
||||
await _db.Updateable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
public async Task Delete(BaseIdListInput input)
|
||||
{
|
||||
if (input.Ids.Count == 0) return;
|
||||
|
||||
var hasBuiltIn = await _db.Queryable<ObVariableDefinition>()
|
||||
.Where(it => input.Ids.Contains(it.Id) && it.IsBuiltIn)
|
||||
.AnyAsync();
|
||||
if (hasBuiltIn)
|
||||
throw Oops.Bah("系统内置的标准入职登记表变量不能删除");
|
||||
|
||||
await _db.Deleteable<ObVariableDefinition>()
|
||||
.Where(it => input.Ids.Contains(it.Id))
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
}
|
||||
@@ -886,7 +886,7 @@
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.ObTaskEmployeeInfo">
|
||||
<summary>
|
||||
候选人在入职任务中提交的固定人员基础信息。
|
||||
候选人在入职任务中提交的《入职登记表》标准员工档案信息。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.TaskId">
|
||||
@@ -896,12 +896,7 @@
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EmployeeNo">
|
||||
<summary>
|
||||
员工编号。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.InternalNo">
|
||||
<summary>
|
||||
内部人员编号。
|
||||
员工编号(选填/人事分配)。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EmployeeName">
|
||||
@@ -909,29 +904,44 @@
|
||||
员工姓名。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.DepartmentName">
|
||||
<summary>
|
||||
所属部门名称。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Gender">
|
||||
<summary>
|
||||
性别。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Phone">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Nation">
|
||||
<summary>
|
||||
手机号码。
|
||||
民族。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.IdCardNumber">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Birthday">
|
||||
<summary>
|
||||
身份证号码。
|
||||
出生年月日。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.College">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.RegisteredResidence">
|
||||
<summary>
|
||||
毕业院校。
|
||||
户籍所在地。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Height">
|
||||
<summary>
|
||||
身高 (cm)。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Weight">
|
||||
<summary>
|
||||
体重 (kg)。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.HealthCondition">
|
||||
<summary>
|
||||
健康状况。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.MaritalStatus">
|
||||
<summary>
|
||||
婚育情况。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Education">
|
||||
@@ -944,64 +954,49 @@
|
||||
所学专业。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.BirthDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.GraduatedSchool">
|
||||
<summary>
|
||||
出生日期。
|
||||
毕业院校。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.RegisteredResidence">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.VocationalQualification">
|
||||
<summary>
|
||||
户籍所在地。
|
||||
职业资格。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Nation">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.QualificationLevel">
|
||||
<summary>
|
||||
民族。
|
||||
资格等级。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ContactAddress">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.TechnicalSpecialty">
|
||||
<summary>
|
||||
现居住或联系地址。
|
||||
有何技术特长。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EntryDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Phone">
|
||||
<summary>
|
||||
入职日期。
|
||||
联系电话/手机号。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ContractStartDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Email">
|
||||
<summary>
|
||||
合同开始日期。
|
||||
电子邮箱。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ContractEndDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.IdCardNumber">
|
||||
<summary>
|
||||
合同结束日期。
|
||||
身份证号码。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ProbationStartDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.CurrentAddress">
|
||||
<summary>
|
||||
试用期开始日期。
|
||||
暂住地址 / 现居住地址。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ProbationEndDate">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.LandlordContact">
|
||||
<summary>
|
||||
试用期结束日期。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.RegularizationDate">
|
||||
<summary>
|
||||
转正日期。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.SocialInsuranceCompany">
|
||||
<summary>
|
||||
社保缴纳公司。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.ContractNature">
|
||||
<summary>
|
||||
合同性质。
|
||||
房东联系方式。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.BankCardNumber">
|
||||
@@ -1009,19 +1004,69 @@
|
||||
工资银行卡号。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.BankAccountName">
|
||||
<summary>
|
||||
银行卡开户名。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.BankName">
|
||||
<summary>
|
||||
开户银行名称。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.Remark">
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.BankAccountName">
|
||||
<summary>
|
||||
业务备注。
|
||||
银行卡开户人姓名。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EmergencyContact">
|
||||
<summary>
|
||||
紧急联系人姓名。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EmergencyPhone">
|
||||
<summary>
|
||||
紧急联系人电话。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EmergencyAddress">
|
||||
<summary>
|
||||
紧急联系人联系地址。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.EducationHistoryJson">
|
||||
<summary>
|
||||
教育学习经历 JSON 列表: [ { timeRange, location, content, result } ]
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.WorkHistoryJson">
|
||||
<summary>
|
||||
主要工作经历 JSON 列表: [ { timeRange, companyName, salary, position, leaveReason } ]
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.FamilyMembersJson">
|
||||
<summary>
|
||||
家庭成员 JSON 列表: [ { name, relationship, age, company, phone } ]
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.OnboardingDepartment">
|
||||
<summary>
|
||||
入职部门。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.OnboardingDate">
|
||||
<summary>
|
||||
入职时间。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.OnboardingPosition">
|
||||
<summary>
|
||||
入职岗位。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.OtherRemarks">
|
||||
<summary>
|
||||
其他说明。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObTaskEmployeeInfo.CustomVariablesJson">
|
||||
<summary>
|
||||
员工补充自定义变量键值 JSON: { "VariableName": "Value" }
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.ObTaskFormRequirement">
|
||||
@@ -1354,6 +1399,57 @@
|
||||
业务备注。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.ObVariableDefinition">
|
||||
<summary>
|
||||
全局合同变量字典定义表。
|
||||
包含标准入职登记表变量、人事合同变量及企业自定义变量。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.VariableCode">
|
||||
<summary>
|
||||
变量全编码,如 employee.EmployeeName, hr.BaseSalary, company.CompanyName, system.TaskNo。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.VariableName">
|
||||
<summary>
|
||||
变量中文显示名称,如“员工姓名”、“基本工资”。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.VariableCategory">
|
||||
<summary>
|
||||
变量作用域分类:employee(员工变量), hr(人事参数), company(公司变量), system(系统变量)。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.DataType">
|
||||
<summary>
|
||||
数据类型:string, number, date, multiline。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.DefaultValue">
|
||||
<summary>
|
||||
默认值或占位提示。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.IsBuiltIn">
|
||||
<summary>
|
||||
是否为入职登记表内置字段(内置字段不可删,且第1步自动收集)。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.Required">
|
||||
<summary>
|
||||
是否必填。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.SortCode">
|
||||
<summary>
|
||||
排序码。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.ObVariableDefinition.Remark">
|
||||
<summary>
|
||||
变量说明/备注。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingTaskStatus">
|
||||
<summary>
|
||||
入职任务状态。
|
||||
@@ -1629,6 +1725,11 @@
|
||||
退回入职任务,保存审核意见并允许候选人补充资料。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingAuditService.ParseDate(System.String)">
|
||||
<summary>
|
||||
将登记表中的日期文本转换为正式员工档案日期。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingCompanyPageInput">
|
||||
<summary>
|
||||
入职业务公司分页查询参数。
|
||||
@@ -2926,6 +3027,21 @@
|
||||
系统文件 Id。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingDeleteMaterialInput">
|
||||
<summary>
|
||||
删除员工在当前可编辑任务中上传的一条材料。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingDeleteMaterialInput.Token">
|
||||
<summary>
|
||||
员工填写链接中的明文 Token。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingDeleteMaterialInput.TaskMaterialId">
|
||||
<summary>
|
||||
任务材料记录 Id。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingConfirmContractInput">
|
||||
<summary>
|
||||
员工确认阅读合同参数。
|
||||
@@ -2966,6 +3082,11 @@
|
||||
关联候选人已经上传的系统文件与材料类型。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.IOnboardingPublicSubmissionService.DeleteMaterial(SimpleAdmin.Application.OnboardingDeleteMaterialInput)">
|
||||
<summary>
|
||||
删除可编辑任务中的一条已上传材料关联。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.IOnboardingPublicSubmissionService.ConfirmContract(SimpleAdmin.Application.OnboardingConfirmContractInput)">
|
||||
<summary>
|
||||
记录候选人已阅读并确认指定任务合同。
|
||||
@@ -2996,6 +3117,11 @@
|
||||
关联已上传 OSS 文件与任务材料要求。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingPublicSubmissionService.DeleteMaterial(SimpleAdmin.Application.OnboardingDeleteMaterialInput)">
|
||||
<summary>
|
||||
任务仍可编辑时删除一条已上传材料。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingPublicSubmissionService.ConfirmContract(SimpleAdmin.Application.OnboardingConfirmContractInput)">
|
||||
<summary>
|
||||
记录候选人已经查看并确认动态生成的合同。
|
||||
@@ -3038,7 +3164,7 @@
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.Detail(SimpleAdmin.Application.OnboardingTaskPublicAccessInput)">
|
||||
<summary>
|
||||
通过有效 Token 获取任务创建时冻结的字段、材料和合同信息。
|
||||
通过有效 Token 获取任务创建时冻结的材料、合同和新版入职登记表信息。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.SaveEmployeeInfo(SimpleAdmin.Application.OnboardingTaskPublicSaveInput)">
|
||||
@@ -3456,6 +3582,46 @@
|
||||
是否必填、必传或必签。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingPublicContractVariableOutput">
|
||||
<summary>
|
||||
员工端需要填写的合同员工变量。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.VariableCode">
|
||||
<summary>
|
||||
合同变量编码。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.VariableName">
|
||||
<summary>
|
||||
合同变量显示名称。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.VariableType">
|
||||
<summary>
|
||||
变量来源类型。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.DataType">
|
||||
<summary>
|
||||
变量数据类型。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.DefaultValue">
|
||||
<summary>
|
||||
变量默认值。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.OptionsJson">
|
||||
<summary>
|
||||
选择型变量的可选项 JSON。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingPublicContractVariableOutput.Required">
|
||||
<summary>
|
||||
是否必填。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.OnboardingPublicMaterialOutput">
|
||||
<summary>
|
||||
员工端材料上传要求。
|
||||
@@ -3526,6 +3692,11 @@
|
||||
候选人已上传材料列表。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SimpleAdmin.Application.OnboardingTaskPublicDetailOutput.ContractVariables">
|
||||
<summary>
|
||||
合同中由员工填写的扩展变量。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.IOnboardingTaskService">
|
||||
<summary>
|
||||
定义入职任务创建业务能力。
|
||||
@@ -3543,7 +3714,7 @@
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingTaskService.Create(SimpleAdmin.Application.OnboardingTaskCreateInput)">
|
||||
<summary>
|
||||
校验公司、岗位和入职模板后创建任务,并冻结合同、补充字段及材料要求。
|
||||
校验公司、岗位和入职模板后创建任务,并冻结合同及材料要求。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingTaskService.ApplyInitialContractVariables(System.Collections.Generic.List{SimpleAdmin.Application.OnboardingInitialContractVariableInput},System.Collections.Generic.List{SimpleAdmin.Application.ObTaskContract})">
|
||||
@@ -3551,6 +3722,16 @@
|
||||
校验并保存任务创建时填写的人事合同变量。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingTaskService.ValidateInitialContractDateRanges(System.Collections.Generic.List{SimpleAdmin.Application.OnboardingInitialContractVariableInput})">
|
||||
<summary>
|
||||
校验人事创建任务时填写的合同日期先后关系。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SimpleAdmin.Application.OnboardingTaskService.ValidateDateRange(System.Collections.Generic.IEnumerable{SimpleAdmin.Application.OnboardingInitialContractVariableInput},System.String,System.String,System.String)">
|
||||
<summary>
|
||||
校验同一合同版本内一组开始、结束日期。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:SimpleAdmin.Application.IOrgService">
|
||||
<summary>
|
||||
机构服务
|
||||
|
||||
Reference in New Issue
Block a user