新增公司盖章与骑缝章配置

This commit is contained in:
fuenmao
2026-10-15 17:41:55 +08:00
parent 0bb8263431
commit 83854ce901
20 changed files with 607 additions and 166 deletions
@@ -52,6 +52,12 @@ public class ObContractTemplateVersion : BaseEntity
/// </summary>
public string VersionStatus { get; set; } = ContractTemplateVersionStatus.Draft;
/// <summary>本版本是否需要公司盖章;历史空值沿用需要盖章。</summary>
public bool? CompanySealEnabled { get; set; }
/// <summary>本版本是否需要骑缝章;历史空值沿用系统骑缝章配置。</summary>
public bool? AcrossPageSealEnabled { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
@@ -52,6 +52,12 @@ public class ObElectronicSignDocument : BaseEntity
/// </summary>
public string CompanySealKeyword { get; set; }
/// <summary>发起本次签约时冻结的公司盖章要求。</summary>
public bool? CompanySealEnabled { get; set; }
/// <summary>发起本次签约时冻结的骑缝章要求。</summary>
public bool? AcrossPageSealEnabled { get; set; }
/// <summary>
/// 契约锁员工签署动作 Id。
/// </summary>
@@ -52,6 +52,12 @@ public class ObTaskContract : BaseEntity
/// </summary>
public int PrintCopies { get; set; } = 1;
/// <summary>任务创建时冻结的公司盖章要求;历史空值沿用需要盖章。</summary>
public bool? CompanySealEnabled { get; set; }
/// <summary>任务创建时冻结的骑缝章要求;历史空值沿用系统配置。</summary>
public bool? AcrossPageSealEnabled { get; set; }
/// <summary>
/// 任务合同当前状态。
/// </summary>
@@ -86,12 +86,12 @@ public class QiyuesuoSettingOptions
public decimal CompanySealOffsetY { get; set; }
/// <summary>
/// 是否在后台确认企业盖章时同时加盖骑缝章。
/// 历史版本未单独设置开关时,是否在企业盖章时加盖骑缝章;新版本显式开关优先。
/// </summary>
public bool EnableAcrossPageSeal { get; set; } = true;
/// <summary>
/// 骑缝章文档范围:ALL_DOCUMENT(全部文档合并)或 SINGLE_DOCUMENT(每份文档单独)。
/// 骑缝章方式:ALL_DOCUMENT(所选文档合并)或 SINGLE_DOCUMENT(所选文档各自独立)。
/// </summary>
public string AcrossPageSealType { get; set; } = "ALL_DOCUMENT";
@@ -0,0 +1,25 @@
using SqlSugar;
namespace SimpleAdmin.Application;
/// <summary>版本盖章配置局部更新,避免覆盖另一个开关、版本状态或历史任务快照。</summary>
internal static class ContractTemplateVersionSealConfiguration
{
internal static IUpdateable<ObContractTemplateVersion> BuildUpdate(
ISqlSugarClient db,
OnboardingContractVersionSealInput input)
{
if (input.Id <= 0)
throw Oops.Bah("版本Id不能为空");
if (!input.CompanySealEnabled.HasValue && !input.AcrossPageSealEnabled.HasValue)
throw Oops.Bah("请指定需要修改的盖章开关");
var update = db.Updateable<ObContractTemplateVersion>()
.Where(item => item.Id == input.Id);
if (input.CompanySealEnabled.HasValue)
update = update.SetColumns(item => item.CompanySealEnabled == input.CompanySealEnabled);
if (input.AcrossPageSealEnabled.HasValue)
update = update.SetColumns(item => item.AcrossPageSealEnabled == input.AcrossPageSealEnabled);
return update;
}
}
@@ -55,6 +55,12 @@ public class OnboardingContractVersionAddInput
/// </summary>
public DateTime? ExpiryDate { get; set; }
/// <summary>本版本是否需要公司盖章;旧客户端未传时沿用原规则。</summary>
public bool? CompanySealEnabled { get; set; }
/// <summary>本版本是否需要骑缝章;旧客户端未传时沿用系统配置。</summary>
public bool? AcrossPageSealEnabled { get; set; }
/// <summary>
/// 业务备注。
/// </summary>
@@ -78,3 +84,19 @@ public class OnboardingContractVersionStatusInput
[global::System.ComponentModel.DataAnnotations.Required(ErrorMessage = "版本状态不能为空")]
public string VersionStatus { get; set; }
}
/// <summary>
/// 修改合同模板版本的盖章配置;未传的开关保持不变。
/// </summary>
public class OnboardingContractVersionSealInput
{
/// <summary>合同版本 Id。</summary>
[IdNotNull(ErrorMessage = "版本Id不能为空")]
public long Id { get; set; }
/// <summary>是否需要公司盖章。</summary>
public bool? CompanySealEnabled { get; set; }
/// <summary>是否需要骑缝章。</summary>
public bool? AcrossPageSealEnabled { get; set; }
}
@@ -50,6 +50,11 @@ public interface IOnboardingContractTemplateService : ITransient
/// </summary>
Task SetVersionStatus(OnboardingContractVersionStatusInput input);
/// <summary>
/// 修改合同模板版本的盖章配置,仅影响后续新建任务。
/// </summary>
Task SetVersionSeals(OnboardingContractVersionSealInput input);
/// <summary>
/// 删除未被入职模板或任务使用的合同版本。
/// </summary>
@@ -272,11 +272,21 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
/// </summary>
public async Task<SqlSugarPagedList<ObContractTemplateVersion>> VersionPage(OnboardingContractVersionPageInput input)
{
return await Context.Queryable<ObContractTemplateVersion>()
var page = await Context.Queryable<ObContractTemplateVersion>()
.Where(it => it.TemplateId == input.TemplateId)
.WhereIF(!string.IsNullOrWhiteSpace(input.VersionStatus), it => it.VersionStatus == input.VersionStatus)
.OrderByDescending(it => it.CreateTime)
.ToPagedListAsync(input.PageNum, input.PageSize);
// 仅解析返回值,不回写历史空值,使列表开关显示真实生效的规则。
var setting = App.GetConfig<QiyuesuoSettingOptions>("QiyuesuoSetting", true)
?? new QiyuesuoSettingOptions();
foreach (var version in page.List)
{
version.CompanySealEnabled = QiyuesuoContractRequestBuilder.CompanySealEnabled(version.CompanySealEnabled);
version.AcrossPageSealEnabled = QiyuesuoContractRequestBuilder.AcrossPageSealEnabled(version.AcrossPageSealEnabled, setting);
}
return page;
}
/// <summary>
@@ -395,7 +405,21 @@ public class OnboardingContractTemplateService : DbRepository<ObContractTemplate
}
version.VersionStatus = input.VersionStatus;
await Context.Updateable(version).ExecuteCommandAsync();
await Context.Updateable(version)
.UpdateColumns(item => new { item.VersionStatus, item.UpdateTime, item.UpdateUserId, item.UpdateUser })
.ExecuteCommandAsync();
}
/// <summary>
/// 修改版本盖章开关;任务和电子签约已经保存独立快照,不随版本变更。
/// </summary>
public async Task SetVersionSeals(OnboardingContractVersionSealInput input)
{
var version = await Context.Queryable<ObContractTemplateVersion>().InSingleAsync(input.Id)
?? throw Oops.Bah("模板版本不存在");
await EnsureTemplateCanManage(version.TemplateId);
await ContractTemplateVersionSealConfiguration.BuildUpdate(Context, input).ExecuteCommandAsync();
}
/// <summary>
@@ -164,4 +164,10 @@ public class OnboardingElectronicSignDocumentOutput
/// <summary>当前管理员流程中是否已生成过员工签后预览。</summary>
public bool EmployeeSignedPreviewed { get; set; }
/// <summary>本份文件是否需要公司盖章。</summary>
public bool CompanySealEnabled { get; set; }
/// <summary>本份文件是否需要骑缝章。</summary>
public bool AcrossPageSealEnabled { get; set; }
}
@@ -805,7 +805,10 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
SealId = process.SealId,
CreatorName = process.CreatorName,
CreatorMobile = process.CreatorMobile,
CallbackUrl = _setting.CallbackUrl
CallbackUrl = _setting.CallbackUrl,
RequiresCompanySign = taskContracts.Any(item =>
QiyuesuoContractRequestBuilder.RequiresCompanySign(
item.CompanySealEnabled, item.AcrossPageSealEnabled, _setting))
});
process.ProviderContractId = GetContractId(providerContract);
process.ProviderStatus = providerContract.Status ?? "DRAFT";
@@ -860,7 +863,9 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
DocumentSort = index + 1,
OriginalDocxFileId = originalFileId,
EmployeeSignKeyword = _setting.EmployeeSignKeyword.Trim(),
CompanySealKeyword = _setting.CompanySealKeyword.Trim(),
CompanySealKeyword = _setting.CompanySealKeyword?.Trim(),
CompanySealEnabled = QiyuesuoContractRequestBuilder.CompanySealEnabled(taskContract.CompanySealEnabled),
AcrossPageSealEnabled = QiyuesuoContractRequestBuilder.AcrossPageSealEnabled(taskContract.AcrossPageSealEnabled, _setting),
Status = CommonStatusConst.ENABLE,
CreateTime = DateTime.Now,
CreateUserId = process.CreateUserId,
@@ -879,7 +884,7 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
}
/// <summary>
/// 为每份文档分别配置员工签名与企业盖章位置,然后一次性发送整个流程。
/// 全部文档配置员工签名,按每份文件的快照配置企业盖章及骑缝章位置。
/// </summary>
private async Task SendProcess(
ObElectronicSignProcess process,
@@ -891,79 +896,40 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
var personalSignatory = providerContract.Signatories.FirstOrDefault(item =>
string.Equals(item.TenantType, "PERSONAL", StringComparison.OrdinalIgnoreCase))
?? throw Oops.Bah("契约锁草稿未返回员工签署方");
var companySignatory = providerContract.Signatories.FirstOrDefault(item =>
string.Equals(item.TenantType, "COMPANY", StringComparison.OrdinalIgnoreCase))
?? throw Oops.Bah("契约锁草稿未返回企业签署方");
var companyAction = companySignatory.Actions.FirstOrDefault(item =>
string.Equals(item.Type, "COMPANY", StringComparison.OrdinalIgnoreCase))
?? throw Oops.Bah("契约锁草稿未返回企业盖章动作");
var personalSignatoryId = GetSignatoryId(personalSignatory);
var companyActionId = GetActionId(companyAction);
var stampers = new List<QiyuesuoStamperInput>();
var orderedDocuments = documents.OrderBy(item => item.DocumentSort).ToList();
var requiresCompanySign = orderedDocuments.Any(item =>
QiyuesuoContractRequestBuilder.RequiresCompanySign(
item.CompanySealEnabled, item.AcrossPageSealEnabled, _setting));
var companyAction = providerContract.Signatories
.Where(item => string.Equals(item.TenantType, "COMPANY", StringComparison.OrdinalIgnoreCase))
.SelectMany(item => item.Actions)
.FirstOrDefault(item => string.Equals(item.Type, "COMPANY", StringComparison.OrdinalIgnoreCase));
if (requiresCompanySign && companyAction == null)
throw Oops.Bah("契约锁草稿未返回企业盖章动作");
if (!requiresCompanySign && companyAction != null)
throw Oops.Bah("本次材料仅需员工签字,但契约锁业务分类仍预设企业盖章节点,请先调整该业务分类的签署流程");
var personalSignatoryId = GetSignatoryId(personalSignatory);
var companyActionId = companyAction == null ? null : GetActionId(companyAction);
var signingDocuments = orderedDocuments.Select(item =>
new OnboardingSigningDocument(
item.ProviderDocumentId,
item.EmployeeSignKeyword,
item.CompanySealKeyword,
item.CompanySealEnabled,
item.AcrossPageSealEnabled)).ToList();
var stampers = QiyuesuoContractRequestBuilder.BuildStampers(
signingDocuments, personalSignatoryId, companyActionId, process.SealId, _setting);
foreach (var document in orderedDocuments)
{
document.EmployeeActionId = personalSignatoryId;
document.CompanyActionId = companyActionId;
document.CompanyActionId = QiyuesuoContractRequestBuilder.RequiresCompanySign(
document.CompanySealEnabled, document.AcrossPageSealEnabled, _setting)
? companyActionId
: null;
document.UpdateTime = DateTime.Now;
await _db.Updateable(document).ExecuteCommandAsync();
stampers.Add(new QiyuesuoStamperInput
{
SignatoryId = personalSignatoryId,
Type = "PERSONAL",
DocumentId = document.ProviderDocumentId,
Keyword = document.EmployeeSignKeyword,
KeywordIndex = Math.Max(1, _setting.EmployeeSignKeywordIndex)
});
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "COMPANY",
DocumentId = document.ProviderDocumentId,
SealId = process.SealId,
Keyword = document.CompanySealKeyword,
KeywordIndex = Math.Max(1, _setting.CompanySealKeywordIndex),
OffsetX = _setting.CompanySealOffsetX,
OffsetY = _setting.CompanySealOffsetY
});
}
if (_setting.EnableAcrossPageSeal)
{
var providerDocumentIds = orderedDocuments
.Select(item => item.ProviderDocumentId)
.Where(item => !string.IsNullOrWhiteSpace(item))
.ToList();
if (providerDocumentIds.Count == 0)
throw Oops.Bah("契约锁未返回可用于骑缝章的合同文档 Id");
var acrossType = _setting.AcrossPageSealType.Trim().ToUpperInvariant();
if (acrossType == "ALL_DOCUMENT")
{
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "ACROSS_PAGE",
DocumentId = providerDocumentIds[0],
DocumentIds = string.Join(",", providerDocumentIds),
SealId = process.SealId,
AcrossType = acrossType
});
}
else
{
foreach (var providerDocumentId in providerDocumentIds)
{
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "ACROSS_PAGE",
DocumentId = providerDocumentId,
SealId = process.SealId,
AcrossType = acrossType
});
}
}
}
var sent = await _qiyuesuoClient.Send(new QiyuesuoSendContractInput
@@ -1179,7 +1145,9 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
DocumentName = item.ContractName,
DocumentSort = index + 1,
OriginalDocxFileId = item.GeneratedDocxFileId ?? 0,
SignedPdfFileId = item.GeneratedPdfFileId
SignedPdfFileId = item.GeneratedPdfFileId,
CompanySealEnabled = QiyuesuoContractRequestBuilder.CompanySealEnabled(item.CompanySealEnabled),
AcrossPageSealEnabled = QiyuesuoContractRequestBuilder.AcrossPageSealEnabled(item.AcrossPageSealEnabled, _setting)
}).ToList();
return result;
}
@@ -1219,6 +1187,8 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
DocumentSort = item.DocumentSort,
OriginalDocxFileId = item.OriginalDocxFileId,
SignedPdfFileId = item.SignedPdfFileId,
CompanySealEnabled = QiyuesuoContractRequestBuilder.CompanySealEnabled(item.CompanySealEnabled),
AcrossPageSealEnabled = QiyuesuoContractRequestBuilder.AcrossPageSealEnabled(item.AcrossPageSealEnabled, _setting),
EmployeeSignedPreviewed = previewedDocumentIds.Contains(item.Id)
}).ToList();
}
@@ -1236,7 +1206,9 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
DocumentName = item.ContractName,
DocumentSort = index + 1,
OriginalDocxFileId = item.GeneratedDocxFileId ?? 0,
SignedPdfFileId = item.GeneratedPdfFileId
SignedPdfFileId = item.GeneratedPdfFileId,
CompanySealEnabled = QiyuesuoContractRequestBuilder.CompanySealEnabled(item.CompanySealEnabled),
AcrossPageSealEnabled = QiyuesuoContractRequestBuilder.AcrossPageSealEnabled(item.AcrossPageSealEnabled, _setting)
}).ToList();
}
return result;
@@ -1431,15 +1403,7 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
if (status == "DRAFT")
return ElectronicSignStatus.Draft;
var personal = providerContract.Signatories.FirstOrDefault(item =>
string.Equals(item.TenantType, "PERSONAL", StringComparison.OrdinalIgnoreCase));
var employeeSigned = string.Equals(
personal?.Status,
"SIGNED",
StringComparison.OrdinalIgnoreCase);
return employeeSigned
? ElectronicSignStatus.PendingCompanySeal
: ElectronicSignStatus.PendingEmployeeSign;
return QiyuesuoContractRequestBuilder.ResolvePendingStatus(providerContract);
}
private static bool IsTerminal(string status)
@@ -1588,10 +1552,9 @@ public class OnboardingElectronicSignService : IOnboardingElectronicSignService
{
throw Oops.Bah("请配置契约锁企业成员姓名和手机号");
}
if (string.IsNullOrWhiteSpace(_setting.EmployeeSignKeyword)
|| string.IsNullOrWhiteSpace(_setting.CompanySealKeyword))
if (string.IsNullOrWhiteSpace(_setting.EmployeeSignKeyword))
{
throw Oops.Bah("请配置员工签名和企业盖章定位关键字");
throw Oops.Bah("请配置员工签名定位关键字");
}
if (_setting.CompanySealOffsetX <= -1m || _setting.CompanySealOffsetX >= 1m
|| _setting.CompanySealOffsetY <= -1m || _setting.CompanySealOffsetY >= 1m)
@@ -40,84 +40,9 @@ public class QiyuesuoClient : IQiyuesuoClient
public async Task<QiyuesuoContractResult> CreateDraft(
QiyuesuoCreateDraftInput input)
{
if (!long.TryParse(input.SealId, out var sealId))
throw Oops.Bah("契约锁 SealId 配置格式不正确");
var body = new
{
bizId = input.BizId,
subject = input.Subject,
tenantName = input.CompanyName,
description = "OnboardX 入职电子签",
send = false,
callbackUrl = NullIfBlank(input.CallbackUrl),
category = new
{
id = input.CategoryId
},
creator = new
{
name = input.CreatorName,
contact = input.CreatorMobile,
contactType = "MOBILE"
},
signatories = new object[]
{
new
{
tenantType = "PERSONAL",
tenantName = input.EmployeeName,
receiver = new
{
name = input.EmployeeName,
contact = input.EmployeeMobile,
contactType = "MOBILE"
},
serialNo = 1,
signatoryNo = "employee",
actions = new object[]
{
new
{
type = "PERSONAL",
name = "员工本人签署",
serialNo = 0,
actionNo = "employee_sign"
}
}
},
new
{
tenantType = "COMPANY",
tenantName = input.CompanyName,
receiver = new
{
name = input.CreatorName,
contact = input.CreatorMobile,
contactType = "MOBILE"
},
serialNo = 2,
signatoryNo = "company",
actions = new object[]
{
new
{
type = "COMPANY",
name = "企业人工盖章",
serialNo = 0,
autoSign = false,
sealId = input.SealId,
corpSealIds = new[] { sealId },
actionNo = "company_seal"
}
}
}
}
};
return await PostJson<QiyuesuoContractResult>(
"/v2/contract/draft",
body);
QiyuesuoContractRequestBuilder.BuildDraft(input));
}
/// <inheritdoc />
@@ -34,6 +34,9 @@ public class QiyuesuoCreateDraftInput
/// <summary>契约锁服务器回调地址。</summary>
public string CallbackUrl { get; set; }
/// <summary>是否需要企业签章节点;仅员工签字的流程不创建该节点。</summary>
public bool RequiresCompanySign { get; set; } = true;
}
/// <summary>
@@ -0,0 +1,206 @@
namespace SimpleAdmin.Application;
/// <summary>发起签约前按文件冻结的签字、盖章要求。</summary>
internal sealed record OnboardingSigningDocument(
string DocumentId,
string EmployeeSignKeyword,
string CompanySealKeyword,
bool? CompanySealEnabled,
bool? AcrossPageSealEnabled);
/// <summary>构造契约锁请求;无数据库和网络访问,员工签字始终覆盖全部文件。</summary>
internal static class QiyuesuoContractRequestBuilder
{
internal static bool CompanySealEnabled(bool? enabled) => enabled ?? true;
internal static bool AcrossPageSealEnabled(bool? enabled, QiyuesuoSettingOptions setting) =>
enabled ?? setting.EnableAcrossPageSeal;
internal static bool RequiresCompanySign(
bool? companySealEnabled,
bool? acrossPageSealEnabled,
QiyuesuoSettingOptions setting) =>
CompanySealEnabled(companySealEnabled) || AcrossPageSealEnabled(acrossPageSealEnabled, setting);
internal static object BuildDraft(QiyuesuoCreateDraftInput input)
{
long sealId = 0;
if (input.RequiresCompanySign && !long.TryParse(input.SealId, out sealId))
throw Oops.Bah("契约锁 SealId 配置格式不正确");
var signatories = new List<object>
{
new
{
tenantType = "PERSONAL",
tenantName = input.EmployeeName,
receiver = new
{
name = input.EmployeeName,
contact = input.EmployeeMobile,
contactType = "MOBILE"
},
serialNo = 1,
signatoryNo = "employee",
actions = new object[]
{
new
{
type = "PERSONAL",
name = "员工本人签署",
serialNo = 0,
actionNo = "employee_sign"
}
}
}
};
if (input.RequiresCompanySign)
{
signatories.Add(new
{
tenantType = "COMPANY",
tenantName = input.CompanyName,
receiver = new
{
name = input.CreatorName,
contact = input.CreatorMobile,
contactType = "MOBILE"
},
serialNo = 2,
signatoryNo = "company",
actions = new object[]
{
new
{
type = "COMPANY",
name = "企业人工盖章",
serialNo = 0,
autoSign = false,
sealId = input.SealId,
corpSealIds = new[] { sealId },
actionNo = "company_seal"
}
}
});
}
return new
{
bizId = input.BizId,
subject = input.Subject,
tenantName = input.CompanyName,
description = "OnboardX 入职电子签",
send = false,
callbackUrl = string.IsNullOrWhiteSpace(input.CallbackUrl) ? null : input.CallbackUrl.Trim(),
category = new { id = input.CategoryId },
creator = new
{
name = input.CreatorName,
contact = input.CreatorMobile,
contactType = "MOBILE"
},
signatories
};
}
internal static List<QiyuesuoStamperInput> BuildStampers(
IReadOnlyList<OnboardingSigningDocument> documents,
string personalSignatoryId,
string companyActionId,
string sealId,
QiyuesuoSettingOptions setting)
{
if (documents.Count == 0)
throw Oops.Bah("当前电子签流程没有可签署的文件");
if (documents.Any(item => string.IsNullOrWhiteSpace(item.DocumentId)))
throw Oops.Bah("契约锁未返回签署文档 Id");
if (string.IsNullOrWhiteSpace(personalSignatoryId))
throw Oops.Bah("契约锁未返回员工签署方 Id");
if (documents.Any(item => RequiresCompanySign(item.CompanySealEnabled, item.AcrossPageSealEnabled, setting))
&& string.IsNullOrWhiteSpace(companyActionId))
throw Oops.Bah("契约锁草稿未返回企业盖章动作");
var stampers = new List<QiyuesuoStamperInput>();
foreach (var document in documents)
{
if (string.IsNullOrWhiteSpace(document.EmployeeSignKeyword))
throw Oops.Bah("请配置员工签名定位关键字");
stampers.Add(new QiyuesuoStamperInput
{
SignatoryId = personalSignatoryId,
Type = "PERSONAL",
DocumentId = document.DocumentId,
Keyword = document.EmployeeSignKeyword,
KeywordIndex = Math.Max(1, setting.EmployeeSignKeywordIndex)
});
if (CompanySealEnabled(document.CompanySealEnabled))
{
if (string.IsNullOrWhiteSpace(document.CompanySealKeyword))
throw Oops.Bah("需要公司盖章的文件未配置企业盖章定位关键字");
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "COMPANY",
DocumentId = document.DocumentId,
SealId = sealId,
Keyword = document.CompanySealKeyword,
KeywordIndex = Math.Max(1, setting.CompanySealKeywordIndex),
OffsetX = setting.CompanySealOffsetX,
OffsetY = setting.CompanySealOffsetY
});
}
}
// 合并骑缝章也只能包含已开启该开关的文件,不能把只需个人签字的材料混入。
var acrossDocuments = documents
.Where(item => AcrossPageSealEnabled(item.AcrossPageSealEnabled, setting))
.Select(item => item.DocumentId)
.ToList();
if (acrossDocuments.Count == 0)
return stampers;
var acrossType = setting.AcrossPageSealType?.Trim().ToUpperInvariant();
if (acrossType is not ("ALL_DOCUMENT" or "SINGLE_DOCUMENT"))
throw Oops.Bah("契约锁骑缝章模式只能配置为 ALL_DOCUMENT 或 SINGLE_DOCUMENT");
if (acrossType == "ALL_DOCUMENT")
{
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "ACROSS_PAGE",
DocumentId = acrossDocuments[0],
DocumentIds = string.Join(",", acrossDocuments),
SealId = sealId,
AcrossType = acrossType
});
}
else
{
foreach (var documentId in acrossDocuments)
{
stampers.Add(new QiyuesuoStamperInput
{
ActionId = companyActionId,
Type = "ACROSS_PAGE",
DocumentId = documentId,
SealId = sealId,
AcrossType = acrossType
});
}
}
return stampers;
}
internal static string ResolvePendingStatus(QiyuesuoContractResult contract)
{
var employeeSigned = contract.Signatories.Any(item =>
string.Equals(item.TenantType, "PERSONAL", StringComparison.OrdinalIgnoreCase)
&& string.Equals(item.Status, "SIGNED", StringComparison.OrdinalIgnoreCase));
var hasCompanyAction = contract.Signatories.Any(item =>
string.Equals(item.TenantType, "COMPANY", StringComparison.OrdinalIgnoreCase)
&& item.Actions.Any(action => string.Equals(action.Type, "COMPANY", StringComparison.OrdinalIgnoreCase)));
// 纯员工签字流程等待平台 COMPLETE 回执,不制造不存在的企业盖章阶段。
return employeeSigned && hasCompanyAction
? ElectronicSignStatus.PendingCompanySeal
: ElectronicSignStatus.PendingEmployeeSign;
}
}
@@ -171,6 +171,7 @@ public class OnboardingTaskService : IOnboardingTaskService
var contracts = contractConfigs.Select(config =>
{
var template = contractTemplates.First(item => item.Id == config.ContractTemplateId);
var version = taskVersions.First(item => item.Id == config.ContractTemplateVersionId);
return new ObTaskContract
{
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
@@ -180,6 +181,8 @@ public class OnboardingTaskService : IOnboardingTaskService
ContractName = template.TemplateName,
ContractType = template.ContractType,
Required = config.Required,
CompanySealEnabled = version.CompanySealEnabled,
AcrossPageSealEnabled = version.AcrossPageSealEnabled,
PrintCopies = config.PrintCopies
};
}).ToList();
@@ -447,6 +450,8 @@ public class OnboardingTaskService : IOnboardingTaskService
ContractName = source.ContractName,
ContractType = source.ContractType,
Required = source.Required,
CompanySealEnabled = source.CompanySealEnabled,
AcrossPageSealEnabled = source.AcrossPageSealEnabled,
PrintCopies = source.PrintCopies
}).ToList();
await _db.Insertable(copiedContracts).ExecuteCommandAsync();