修改相关bug

This commit is contained in:
fuenmao
2026-09-17 11:37:39 +08:00
parent e9894538e8
commit 9de05b44b8
17 changed files with 171 additions and 30 deletions
@@ -35,35 +35,35 @@ public class ObCompany : BaseEntity
/// <summary>
/// 统一社会信用代码。
/// </summary>
public string UnifiedSocialCreditCode { get; set; }
public virtual string UnifiedSocialCreditCode { get; set; }
/// <summary>
/// 法定代表人姓名。
/// </summary>
public string LegalRepresentative { get; set; }
public virtual string LegalRepresentative { get; set; }
/// <summary>
/// 工商注册地址。
/// </summary>
public string RegisteredAddress { get; set; }
public virtual string RegisteredAddress { get; set; }
/// <summary>
/// 公司联系电话。
/// </summary>
public string ContactPhone { get; set; }
public virtual string ContactPhone { get; set; }
/// <summary>
/// 契约锁默认业务分类 Id;每个签约公司独立配置。
/// </summary>
public string QiyuesuoCategoryId { get; set; }
public virtual string QiyuesuoCategoryId { get; set; }
/// <summary>
/// 契约锁企业印章 Id;每个签约公司独立配置。
/// </summary>
public string QiyuesuoSealId { get; set; }
public virtual string QiyuesuoSealId { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
public string Remark { get; set; }
public virtual string Remark { get; set; }
}
@@ -1,4 +1,4 @@
namespace SimpleAdmin.Application;
namespace SimpleAdmin.Application;
/// <summary>
/// 入职业务部门档案,属于某家入职公司。
@@ -30,7 +30,7 @@ public class ObDepartment : BaseEntity
/// <summary>
/// 业务备注。
/// </summary>
public string Remark { get; set; }
public virtual string Remark { get; set; }
/// <summary>
/// 所属公司名称 (展示用)
@@ -56,7 +56,7 @@ public class ObPosition : BaseEntity
/// <summary>
/// 业务备注。
/// </summary>
public string Remark { get; set; }
public virtual string Remark { get; set; }
/// <summary>
/// 所属公司名称 (展示用)
@@ -0,0 +1,21 @@
namespace SimpleAdmin.Application;
/// <summary>
/// 签署材料模板版本的时间有效性规则。
/// </summary>
internal static class ContractTemplateVersionValidity
{
internal static void ValidateRange(DateTime? effectiveAt, DateTime? expiresAt)
{
if (effectiveAt.HasValue && expiresAt.HasValue && expiresAt.Value <= effectiveAt.Value)
throw Oops.Bah("失效时间必须晚于生效时间");
}
internal static bool IsAvailable(ObContractTemplateVersion version, DateTime now)
{
return version != null
&& version.VersionStatus == ContractTemplateVersionStatus.Enabled
&& (!version.EffectiveDate.HasValue || version.EffectiveDate.Value <= now)
&& (!version.ExpiryDate.HasValue || version.ExpiryDate.Value > now);
}
}
@@ -30,19 +30,64 @@ public class OnboardingCompanyAddInput : ObCompany
/// 公司业务编码。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "公司编码不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "公司编码不能超过50个字符")]
public override string CompanyCode { get; set; }
/// <summary>
/// 公司名称。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "公司名称不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "公司名称不能超过50个字符")]
public override string CompanyName { get; set; }
/// <summary>
/// 合同甲方完整法定名称。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "合同甲方全称不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(100, ErrorMessage = "合同甲方全称不能超过100个字符")]
public override string LegalName { get; set; }
/// <summary>
/// 统一社会信用代码。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(18, ErrorMessage = "统一社会信用代码不能超过18位")]
public override string UnifiedSocialCreditCode { get; set; }
/// <summary>
/// 法定代表人姓名。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(20, ErrorMessage = "法定代表人不能超过20个字符")]
public override string LegalRepresentative { get; set; }
/// <summary>
/// 工商注册地址。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(150, ErrorMessage = "注册地址不能超过150个字符")]
public override string RegisteredAddress { get; set; }
/// <summary>
/// 公司联系电话。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(20, ErrorMessage = "联系电话不能超过20个字符")]
public override string ContactPhone { get; set; }
/// <summary>
/// 契约锁默认业务分类 Id;每个签约公司独立配置。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(19, ErrorMessage = "契约锁业务分类Id不能超过19位数字")]
public override string QiyuesuoCategoryId { get; set; }
/// <summary>
/// 契约锁企业印章 Id;每个签约公司独立配置。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(19, ErrorMessage = "契约锁印章Id不能超过19位数字")]
public override string QiyuesuoSealId { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(300, ErrorMessage = "备注不能超过300个字符")]
public override string Remark { get; set; }
}
/// <summary>
@@ -138,10 +138,16 @@ public class OnboardingCompanyService : DbRepository<ObCompany>, IOnboardingComp
throw Oops.Bah("契约锁默认业务分类 Id 和企业印章 Id 必须同时填写");
if (!hasCategoryId)
return;
if (!company.QiyuesuoCategoryId.All(char.IsDigit)
|| !company.QiyuesuoSealId.All(char.IsDigit))
{
throw Oops.Bah("契约锁默认业务分类 Id 和企业印章 Id 只能填写纯数字");
}
if (!long.TryParse(company.QiyuesuoCategoryId, out _)
|| !long.TryParse(company.QiyuesuoSealId, out _))
{
throw Oops.Bah("契约锁默认业务分类 Id 和企业印章 Id 只能填写数字");
throw Oops.Bah("契约锁默认业务分类 Id 和企业印章 Id 超出有效数字范围(最大支持19位长整数)");
}
}
@@ -153,13 +153,14 @@ public class OnboardingContractDocumentService : IOnboardingContractDocumentServ
var versions = await _db.Queryable<ObContractTemplateVersion>()
.Where(item => versionIds.Contains(item.Id))
.ToListAsync();
var now = DateTime.Now;
var versionsValid = versions.Count == versionIds.Count
&& contractConfigs.All(config => versions.Any(version =>
version.Id == config.ContractTemplateVersionId
&& version.TemplateId == config.ContractTemplateId
&& version.VersionStatus == ContractTemplateVersionStatus.Enabled));
&& ContractTemplateVersionValidity.IsAvailable(version, now)));
if (!versionsValid)
throw Oops.Bah("入职模板包含不存在、未启用或归属错误的合同版本");
throw Oops.Bah("入职模板包含不存在、未生效、已失效、未启用或归属错误的签署材料版本");
var inputs = input.ContractVariables
?? new List<OnboardingInitialContractVariableInput>();
@@ -46,12 +46,12 @@ public class OnboardingContractVersionAddInput
public string FileHash { get; set; }
/// <summary>
/// 生效日期。
/// 生效时间。
/// </summary>
public DateTime? EffectiveDate { get; set; }
/// <summary>
/// 失效日期。
/// 失效时间。
/// </summary>
public DateTime? ExpiryDate { get; set; }
@@ -79,7 +79,21 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
if (candidates.Count == 0)
return candidates;
var now = DateTime.Now;
var candidateIds = candidates.Select(item => item.Id).ToList();
var availableVersionTemplateIds = (await Context.Queryable<ObContractTemplateVersion>()
.Where(item => candidateIds.Contains(item.TemplateId))
.ToListAsync())
.Where(item => ContractTemplateVersionValidity.IsAvailable(item, now))
.Select(item => item.TemplateId)
.ToHashSet();
candidates = candidates
.Where(item => availableVersionTemplateIds.Contains(item.Id))
.ToList();
if (candidates.Count == 0)
return candidates;
candidateIds = candidates.Select(item => item.Id).ToList();
var relations = await Context.Queryable<ObContractTemplatePosition>()
.Where(item => candidateIds.Contains(item.ContractTemplateId))
.ToListAsync();
@@ -270,6 +284,7 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
/// </summary>
public async Task AddVersion(OnboardingContractVersionAddInput input)
{
ContractTemplateVersionValidity.ValidateRange(input.EffectiveDate, input.ExpiryDate);
var template = await Detail(new BaseIdInput { Id = input.TemplateId });
await _dataPermission.EnsureCanManage(
template.CreateUserId,
@@ -357,6 +372,9 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
if (input.VersionStatus == ContractTemplateVersionStatus.Enabled)
{
ContractTemplateVersionValidity.ValidateRange(version.EffectiveDate, version.ExpiryDate);
if (version.ExpiryDate.HasValue && version.ExpiryDate.Value <= DateTime.Now)
throw Oops.Bah("该签署材料版本已经失效,不能启用");
var hasUnresolvedVariables = await Context.Queryable<ObTemplateVariable>()
.AnyAsync(item => item.TemplateVersionId == input.Id
&& item.VariableType == ContractVariableType.Unresolved);
@@ -1,4 +1,4 @@
namespace SimpleAdmin.Application;
namespace SimpleAdmin.Application;
/// <summary>
/// 入职业务部门分页查询参数。
@@ -41,13 +41,21 @@ public class OnboardingDepartmentAddInput : ObDepartment
/// 部门业务编码。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "部门编码不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "部门编码不能超过50个字符")]
public override string DepartmentCode { get; set; }
/// <summary>
/// 部门名称。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "部门名称不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "部门名称不能超过50个字符")]
public override string DepartmentName { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(200, ErrorMessage = "备注不能超过200个字符")]
public override string Remark { get; set; }
}
/// <summary>
@@ -177,8 +177,14 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
throw Oops.Bah($"公司“{companyName}”未配置契约锁默认业务分类 Id,请先到公司与岗位中编辑公司资料");
if (string.IsNullOrWhiteSpace(sealId))
throw Oops.Bah($"公司“{companyName}”未配置契约锁企业印章 Id,请先到公司与岗位中编辑公司资料");
if (!categoryId.All(char.IsDigit)
|| !sealId.All(char.IsDigit))
{
throw Oops.Bah($"公司“{companyName}”的契约锁业务分类或企业印章 Id 只能填写纯数字");
}
if (!long.TryParse(categoryId, out _) || !long.TryParse(sealId, out _))
throw Oops.Bah($"公司“{companyName}”的契约锁业务分类或印章 Id 格式不正确");
throw Oops.Bah($"公司“{companyName}”的契约锁业务分类或企业印章 Id 超出有效范围(最大支持19位长整数)");
var taskContracts = await _db.Queryable<ObTaskContract>()
.Where(item => item.TaskId == task.Id)
@@ -311,6 +311,9 @@ public class OnboardingTemplateService : IOnboardingTemplateService
{
throw Oops.Bah("合同模板与版本不匹配");
}
var now = DateTime.Now;
if (versions.Any(version => !ContractTemplateVersionValidity.IsAvailable(version, now)))
throw Oops.Bah("入职模板只能选择当前已生效且尚未失效的启用签署材料版本");
var contractTemplateIds = input.Contracts
.Select(item => item.ContractTemplateId)
@@ -352,8 +355,6 @@ public class OnboardingTemplateService : IOnboardingTemplateService
"enable",
global::System.StringComparison.OrdinalIgnoreCase)))
throw Oops.Bah("启用入职模板前,请先启用全部合同模板");
if (versions.Any(item => item.VersionStatus != ContractTemplateVersionStatus.Enabled))
throw Oops.Bah("启用入职模板前,请先启用全部合同版本");
}
var materialIds = input.Materials.Select(item => item.MaterialTypeId).ToList();
@@ -1,4 +1,4 @@
namespace SimpleAdmin.Application;
namespace SimpleAdmin.Application;
/// <summary>
/// 入职业务岗位分页查询参数。
@@ -52,13 +52,21 @@ public class OnboardingPositionAddInput : ObPosition
/// 岗位业务编码。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "岗位编码不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "岗位编码不能超过50个字符")]
public override string PositionCode { get; set; }
/// <summary>
/// 岗位名称。
/// </summary>
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "岗位名称不能为空")]
[global::System.ComponentModel.DataAnnotations.MaxLength(50, ErrorMessage = "岗位名称不能超过50个字符")]
public override string PositionName { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
[global::System.ComponentModel.DataAnnotations.MaxLength(200, ErrorMessage = "备注不能超过200个字符")]
public override string Remark { get; set; }
}
/// <summary>
@@ -95,11 +95,13 @@ public class OnboardingTaskService : IOnboardingTaskService
throw Oops.Bah("入职模板包含不适用于当前岗位的合同模板");
var versionIds = contractConfigs.Select(item => item.ContractTemplateVersionId).Distinct().ToList();
var enabledVersionCount = await _db.Queryable<ObContractTemplateVersion>()
.CountAsync(item => versionIds.Contains(item.Id)
&& item.VersionStatus == ContractTemplateVersionStatus.Enabled);
if (enabledVersionCount != versionIds.Count)
throw Oops.Bah("入职模板包含未启用的合同版本,请先调整模板配置");
var now = DateTime.Now;
var taskVersions = await _db.Queryable<ObContractTemplateVersion>()
.Where(item => versionIds.Contains(item.Id))
.ToListAsync();
if (taskVersions.Count != versionIds.Count
|| taskVersions.Any(item => !ContractTemplateVersionValidity.IsAvailable(item, now)))
throw Oops.Bah("入职模板包含未生效、已失效或未启用的签署材料版本,请先调整模板配置");
var materialIds = materialConfigs.Select(item => item.MaterialTypeId).Distinct().ToList();
var materialTypes = materialIds.Count == 0
@@ -290,11 +292,13 @@ public class OnboardingTaskService : IOnboardingTaskService
.Select(item => item.TemplateVersionId)
.Distinct()
.ToList();
var enabledVersionCount = await _db.Queryable<ObContractTemplateVersion>()
.CountAsync(item => versionIds.Contains(item.Id)
&& item.VersionStatus == ContractTemplateVersionStatus.Enabled);
if (enabledVersionCount != versionIds.Count)
throw Oops.Bah("原任务包含已停用的合同版本,不能继续复制");
var now = DateTime.Now;
var copyVersions = await _db.Queryable<ObContractTemplateVersion>()
.Where(item => versionIds.Contains(item.Id))
.ToListAsync();
if (copyVersions.Count != versionIds.Count
|| copyVersions.Any(item => !ContractTemplateVersionValidity.IsAvailable(item, now)))
throw Oops.Bah("原任务包含未生效、已失效或未启用的签署材料版本,不能继续复制");
var sourceMaterialRequirements = await _db.Queryable<ObTaskMaterialRequirement>()
.Where(item => item.TaskId == sourceTask.Id)