修复相关bug
This commit is contained in:
+63
-2
@@ -147,7 +147,7 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
"合同模板");
|
||||
NormalizeInput(input);
|
||||
await ValidateBusinessScope(input.CompanyId, input.DepartmentId, input.PositionIds);
|
||||
await ValidateReferencedOnboardingTemplates(input);
|
||||
await ValidateReferencedOnboardingTemplates(input, template.Status);
|
||||
await EnsureCodeUnique(input.TemplateCode, input.Id);
|
||||
|
||||
var entity = BuildEntity(input.Id, input);
|
||||
@@ -370,6 +370,18 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
?? throw Oops.Bah("模板版本不存在");
|
||||
await EnsureTemplateCanManage(version.TemplateId);
|
||||
|
||||
if (version.VersionStatus == ContractTemplateVersionStatus.Enabled
|
||||
&& input.VersionStatus == ContractTemplateVersionStatus.Disabled)
|
||||
{
|
||||
var referencedNames = await GetEnabledOnboardingTemplateNames(
|
||||
version.TemplateId,
|
||||
version.Id);
|
||||
if (referencedNames.Count > 0)
|
||||
{
|
||||
throw Oops.Bah(
|
||||
$"该签署材料版本正在被启用中的入职模板{FormatTemplateNames(referencedNames)}引用,不能停用,请先调整或停用这些入职模板");
|
||||
}
|
||||
}
|
||||
if (input.VersionStatus == ContractTemplateVersionStatus.Enabled)
|
||||
{
|
||||
ContractTemplateVersionValidity.ValidateRange(version.EffectiveDate, version.ExpiryDate);
|
||||
@@ -550,7 +562,8 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
/// 防止修改合同模板归属后破坏已经保存的入职模板配置。
|
||||
/// </summary>
|
||||
private async Task ValidateReferencedOnboardingTemplates(
|
||||
OnboardingContractTemplateEditInput input)
|
||||
OnboardingContractTemplateEditInput input,
|
||||
string currentStatus)
|
||||
{
|
||||
var relations = await Context.Queryable<ObOnboardingTemplateContract>()
|
||||
.Where(item => item.ContractTemplateId == input.Id)
|
||||
@@ -565,6 +578,21 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
var onboardingTemplates = await Context.Queryable<ObOnboardingTemplate>()
|
||||
.Where(item => onboardingTemplateIds.Contains(item.Id))
|
||||
.ToListAsync();
|
||||
if (string.Equals(currentStatus, "enable", StringComparison.OrdinalIgnoreCase)
|
||||
&& !string.Equals(input.Status, "enable", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var enabledTemplateNames = onboardingTemplates
|
||||
.Where(item => !item.IsDelete && item.Status == "enable")
|
||||
.Select(item => item.TemplateName)
|
||||
.Distinct()
|
||||
.OrderBy(item => item)
|
||||
.ToList();
|
||||
if (enabledTemplateNames.Count > 0)
|
||||
{
|
||||
throw Oops.Bah(
|
||||
$"该签署材料模板正在被启用中的入职模板{FormatTemplateNames(enabledTemplateNames)}引用,不能停用,请先调整或停用这些入职模板");
|
||||
}
|
||||
}
|
||||
var positionRelations = await Context.Queryable<ObOnboardingTemplatePosition>()
|
||||
.Where(item => onboardingTemplateIds.Contains(item.OnboardingTemplateId))
|
||||
.ToListAsync();
|
||||
@@ -589,6 +617,39 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<string>> GetEnabledOnboardingTemplateNames(
|
||||
long contractTemplateId,
|
||||
long? contractTemplateVersionId = null)
|
||||
{
|
||||
var relations = await Context.Queryable<ObOnboardingTemplateContract>()
|
||||
.Where(item => item.ContractTemplateId == contractTemplateId)
|
||||
.WhereIF(contractTemplateVersionId.HasValue,
|
||||
item => item.ContractTemplateVersionId == contractTemplateVersionId.Value)
|
||||
.ToListAsync();
|
||||
if (relations.Count == 0)
|
||||
return new List<string>();
|
||||
|
||||
var onboardingTemplateIds = relations
|
||||
.Select(item => item.OnboardingTemplateId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
var names = await Context.Queryable<ObOnboardingTemplate>()
|
||||
.Where(item => onboardingTemplateIds.Contains(item.Id)
|
||||
&& !item.IsDelete
|
||||
&& item.Status == "enable")
|
||||
.Select(item => item.TemplateName)
|
||||
.ToListAsync();
|
||||
return names
|
||||
.Where(item => !string.IsNullOrWhiteSpace(item))
|
||||
.Distinct()
|
||||
.OrderBy(item => item)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static string FormatTemplateNames(IEnumerable<string> templateNames)
|
||||
{
|
||||
return string.Join("、", templateNames.Select(item => $"“{item}”"));
|
||||
}
|
||||
/// <summary>
|
||||
/// 构建合同模板主档案实体。
|
||||
/// </summary>
|
||||
|
||||
+27
-4
@@ -31,6 +31,14 @@ public class OnboardingIdentityValidationService : IOnboardingIdentityValidation
|
||||
throw Oops.Bah("该姓名和身份证号已完成正式员工建档,请勿重复提交入职资料");
|
||||
}
|
||||
|
||||
// 身份证号码代表唯一自然人。即使姓名填写不同,也不能绕过正式员工重复校验。
|
||||
var formalEmployeeIdCardExists = await _db.Queryable<ObEmployee>()
|
||||
.AnyAsync(item => item.IdCardNumber == idCardNumber);
|
||||
if (formalEmployeeIdCardExists)
|
||||
{
|
||||
throw Oops.Bah("该身份证号码已完成正式员工建档,请核对姓名和身份证号码;如需更正,请联系 HR");
|
||||
}
|
||||
|
||||
// 待填写任务不占用身份,以实际先提交的任务为准;撤销或过期任务允许重新发起。
|
||||
var duplicateTaskExists = await _db.Queryable<ObTaskEmployeeInfo>()
|
||||
.InnerJoin<ObOnboardingTask>((info, task) => info.TaskId == task.Id)
|
||||
@@ -42,9 +50,24 @@ public class OnboardingIdentityValidationService : IOnboardingIdentityValidation
|
||||
|| task.TaskStatus == OnboardingTaskStatus.Approved
|
||||
|| task.TaskStatus == OnboardingTaskStatus.Archived))
|
||||
.AnyAsync();
|
||||
if (!duplicateTaskExists)
|
||||
return;
|
||||
if (duplicateTaskExists)
|
||||
{
|
||||
throw Oops.Bah("该姓名和身份证号已存在正在办理的入职任务,请勿重复提交;如需补充材料,请联系 HR 继续使用原任务链接");
|
||||
}
|
||||
|
||||
throw Oops.Bah("该姓名和身份证号已存在正在办理的入职任务,请勿重复提交;如需补充材料,请联系 HR 继续使用原任务链接");
|
||||
// 再单独按身份证号码校验,防止不同姓名使用同一证件重复提交不同任务。
|
||||
var duplicateIdCardTaskExists = await _db.Queryable<ObTaskEmployeeInfo>()
|
||||
.InnerJoin<ObOnboardingTask>((info, task) => info.TaskId == task.Id)
|
||||
.Where((info, task) => info.TaskId != currentTaskId
|
||||
&& info.IdCardNumber == idCardNumber
|
||||
&& (task.TaskStatus == OnboardingTaskStatus.Reviewing
|
||||
|| task.TaskStatus == OnboardingTaskStatus.Rejected
|
||||
|| task.TaskStatus == OnboardingTaskStatus.Approved
|
||||
|| task.TaskStatus == OnboardingTaskStatus.Archived))
|
||||
.AnyAsync();
|
||||
if (duplicateIdCardTaskExists)
|
||||
{
|
||||
throw Oops.Bah("该身份证号码已存在正在办理的入职任务,请核对姓名和身份证号码;如需补充材料,请联系 HR 继续使用原任务链接");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-1
@@ -229,7 +229,65 @@ public class OnboardingTemplateService : IOnboardingTemplateService
|
||||
&& templateIds.Contains(item.Id))
|
||||
.OrderBy(item => item.TemplateName)
|
||||
.ToListAsync();
|
||||
return await BuildOutputs(templates);
|
||||
if (templates.Count == 0)
|
||||
return await BuildOutputs(templates);
|
||||
|
||||
var onboardingTemplateIds = templates.Select(item => item.Id).ToList();
|
||||
var contractConfigs = await _db.Queryable<ObOnboardingTemplateContract>()
|
||||
.Where(item => onboardingTemplateIds.Contains(item.OnboardingTemplateId))
|
||||
.ToListAsync();
|
||||
if (contractConfigs.Count == 0)
|
||||
return await BuildOutputs(new List<ObOnboardingTemplate>());
|
||||
|
||||
var contractTemplateIds = contractConfigs
|
||||
.Select(item => item.ContractTemplateId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
var contractVersionIds = contractConfigs
|
||||
.Select(item => item.ContractTemplateVersionId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
var contractTemplates = await _db.Queryable<ObContractTemplate>()
|
||||
.Where(item => contractTemplateIds.Contains(item.Id))
|
||||
.ToListAsync();
|
||||
var contractVersions = await _db.Queryable<ObContractTemplateVersion>()
|
||||
.Where(item => contractVersionIds.Contains(item.Id))
|
||||
.ToListAsync();
|
||||
var contractPositions = await _db.Queryable<ObContractTemplatePosition>()
|
||||
.Where(item => contractTemplateIds.Contains(item.ContractTemplateId)
|
||||
&& item.PositionId == positionId)
|
||||
.ToListAsync();
|
||||
var now = DateTime.Now;
|
||||
var availableTemplates = templates.Where(template =>
|
||||
{
|
||||
var configs = contractConfigs
|
||||
.Where(item => item.OnboardingTemplateId == template.Id)
|
||||
.ToList();
|
||||
if (configs.Count == 0)
|
||||
return false;
|
||||
|
||||
return configs.All(config =>
|
||||
{
|
||||
var contractTemplate = contractTemplates
|
||||
.FirstOrDefault(item => item.Id == config.ContractTemplateId);
|
||||
var version = contractVersions
|
||||
.FirstOrDefault(item => item.Id == config.ContractTemplateVersionId);
|
||||
return contractTemplate != null
|
||||
&& string.Equals(
|
||||
contractTemplate.Status,
|
||||
"enable",
|
||||
StringComparison.OrdinalIgnoreCase)
|
||||
&& contractTemplate.CompanyId == template.CompanyId
|
||||
&& contractTemplate.DepartmentId == template.DepartmentId
|
||||
&& contractPositions.Any(item =>
|
||||
item.ContractTemplateId == config.ContractTemplateId)
|
||||
&& version != null
|
||||
&& version.TemplateId == config.ContractTemplateId
|
||||
&& ContractTemplateVersionValidity.IsAvailable(version, now);
|
||||
});
|
||||
}).ToList();
|
||||
|
||||
return await BuildOutputs(availableTemplates);
|
||||
}
|
||||
|
||||
private static void NormalizeAndValidateInput(OnboardingTemplateSaveInput input)
|
||||
|
||||
@@ -25,6 +25,10 @@ public class ConfigService : DbRepository<SysConfig>, IConfigService
|
||||
/// <inheritdoc/>
|
||||
public async Task<List<SysConfig>> GetConfigsByCategory(string category)
|
||||
{
|
||||
// 业务自定义配置需立即生效,始终以数据库中的最新数据为准。
|
||||
if (category == CateGoryConst.CONFIG_BIZ_DEFINE)
|
||||
return await GetListAsync(it => it.Category == category);
|
||||
|
||||
var key = SystemConst.CACHE_DEV_CONFIG + category;//系统配置key
|
||||
//先从redis拿配置
|
||||
var configList = _simpleCacheService.HashGetAll<SysConfig>(key).Values.ToList();
|
||||
@@ -51,6 +55,10 @@ public class ConfigService : DbRepository<SysConfig>, IConfigService
|
||||
/// <inheritdoc/>
|
||||
public async Task<SysConfig> GetByConfigKey(string category, string configKey)
|
||||
{
|
||||
// 业务自定义配置不走缓存,避免修改后仍读取到本机旧值。
|
||||
if (category == CateGoryConst.CONFIG_BIZ_DEFINE)
|
||||
return await GetFirstAsync(it => it.Category == category && it.ConfigKey == configKey);
|
||||
|
||||
var key = SystemConst.CACHE_DEV_CONFIG + category;//系统配置key
|
||||
//先从redis拿配置
|
||||
var config = _simpleCacheService.HashGetOne<SysConfig>(key, configKey);
|
||||
|
||||
Reference in New Issue
Block a user