111
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
|
<!-- 由 SDK 按目标框架输出 XML,避免 net6/net7/net8 并行编译时共同写入项目根目录的同名文件。 -->
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+5
-3
@@ -61,18 +61,20 @@ public class OnboardingContractDocumentService : IOnboardingContractDocumentServ
|
|||||||
item => item.VariableCode,
|
item => item.VariableCode,
|
||||||
item => item.VariableValue ?? string.Empty,
|
item => item.VariableValue ?? string.Empty,
|
||||||
StringComparer.OrdinalIgnoreCase));
|
StringComparer.OrdinalIgnoreCase));
|
||||||
var name = $"{task.TaskNo}_{contract.ContractName}.docx";
|
var generatedAt = DateTime.Now;
|
||||||
|
// 在文件名中加入生成批次,避免手机系统把同名的新合同误认为历史下载文件。
|
||||||
|
var name = $"{task.TaskNo}_{contract.ContractName}_{generatedAt:yyyyMMddHHmmssfff}.docx";
|
||||||
var fileId = await _fileService.StoreGeneratedFile(
|
var fileId = await _fileService.StoreGeneratedFile(
|
||||||
SysDictConst.FILE_ENGINE_ALIYUN_OSS,
|
SysDictConst.FILE_ENGINE_ALIYUN_OSS,
|
||||||
name,
|
name,
|
||||||
rendered);
|
rendered);
|
||||||
|
|
||||||
contract.GeneratedDocxFileId = fileId;
|
contract.GeneratedDocxFileId = fileId;
|
||||||
contract.GeneratedAt = DateTime.Now;
|
contract.GeneratedAt = generatedAt;
|
||||||
contract.ContractStatus = task.TaskStatus == OnboardingTaskStatus.Approved
|
contract.ContractStatus = task.TaskStatus == OnboardingTaskStatus.Approved
|
||||||
? TaskContractStatus.OfflinePendingSign
|
? TaskContractStatus.OfflinePendingSign
|
||||||
: TaskContractStatus.PendingConfirm;
|
: TaskContractStatus.PendingConfirm;
|
||||||
await _db.Updateable(contract).ExecuteCommandAsync();
|
await _db.Updateable(contract).ExecuteCommandAsync();
|
||||||
return fileId;
|
return fileId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -14,7 +14,13 @@ public interface IOnboardingPublicTaskService : ITransient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Task SaveEmployeeInfo(OnboardingTaskPublicSaveInput input);
|
Task SaveEmployeeInfo(OnboardingTaskPublicSaveInput input);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 校验任务归属后返回合同模板源文件 Id。
|
/// 校验合同变量并提前生成候选人的合同 DOCX。
|
||||||
|
/// </summary>
|
||||||
|
Task<OnboardingPublicContractPrepareOutput> PrepareContract(
|
||||||
|
OnboardingPublicContractSourceInput input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 校验任务归属后返回已经准备完成的合同文件 Id。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input);
|
Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input);
|
||||||
|
|
||||||
|
|||||||
+49
-3
@@ -162,25 +162,71 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据员工当前已填写信息生成合同预览,并返回已替换变量的 DOCX 文件 Id。
|
/// 根据员工当前已填写信息校验变量并提前生成合同 DOCX。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input)
|
public async Task<OnboardingPublicContractPrepareOutput> PrepareContract(
|
||||||
|
OnboardingPublicContractSourceInput input)
|
||||||
{
|
{
|
||||||
var link = await GetActiveLink(input.Token);
|
var link = await GetActiveLink(input.Token);
|
||||||
var contract = await _db.Queryable<ObTaskContract>()
|
var contract = await _db.Queryable<ObTaskContract>()
|
||||||
.FirstAsync(item => item.Id == input.TaskContractId && item.TaskId == link.TaskId)
|
.FirstAsync(item => item.Id == input.TaskContractId && item.TaskId == link.TaskId)
|
||||||
?? throw Oops.Bah("合同不存在");
|
?? throw Oops.Bah("合同不存在");
|
||||||
|
|
||||||
|
// 员工资料保存时会清除旧文件 Id;仍有文件 Id 时还需确认文件记录没有被异常删除。
|
||||||
|
if (contract.GeneratedDocxFileId.HasValue)
|
||||||
|
{
|
||||||
|
var generatedFileExists = await _db.Queryable<SysFile>()
|
||||||
|
.AnyAsync(item => item.Id == contract.GeneratedDocxFileId.Value);
|
||||||
|
if (!generatedFileExists)
|
||||||
|
throw Oops.Bah("已生成的合同文件不存在,请联系管理员重新生成");
|
||||||
|
|
||||||
|
return new OnboardingPublicContractPrepareOutput
|
||||||
|
{
|
||||||
|
FileId = contract.GeneratedDocxFileId.Value,
|
||||||
|
GeneratedAt = contract.GeneratedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
await _snapshotService.Build(link.TaskId);
|
await _snapshotService.Build(link.TaskId);
|
||||||
var fileId = await _contractDocumentService.Generate(new OnboardingGenerateContractInput
|
var fileId = await _contractDocumentService.Generate(new OnboardingGenerateContractInput
|
||||||
{
|
{
|
||||||
TaskContractId = contract.Id
|
TaskContractId = contract.Id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var generatedAt = await _db.Queryable<ObTaskContract>()
|
||||||
|
.Where(item => item.Id == contract.Id)
|
||||||
|
.Select(item => item.GeneratedAt)
|
||||||
|
.SingleAsync();
|
||||||
|
return new OnboardingPublicContractPrepareOutput
|
||||||
|
{
|
||||||
|
FileId = fileId,
|
||||||
|
GeneratedAt = generatedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回已经准备完成的合同文件,下载阶段不再执行变量校验和文档生成。
|
||||||
|
/// </summary>
|
||||||
|
public async Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input)
|
||||||
|
{
|
||||||
|
var link = await GetActiveLink(input.Token);
|
||||||
|
var contract = await _db.Queryable<ObTaskContract>()
|
||||||
|
.FirstAsync(item => item.Id == input.TaskContractId && item.TaskId == link.TaskId)
|
||||||
|
?? throw Oops.Bah("合同不存在");
|
||||||
|
var fileId = contract.GeneratedDocxFileId
|
||||||
|
?? throw Oops.Bah("合同尚未准备完成,请刷新页面后重试");
|
||||||
|
var fileExists = await _db.Queryable<SysFile>()
|
||||||
|
.AnyAsync(item => item.Id == fileId);
|
||||||
|
if (!fileExists)
|
||||||
|
throw Oops.Bah("合同文件不存在,请重新准备合同");
|
||||||
|
|
||||||
contract.ReadAt ??= DateTime.Now;
|
contract.ReadAt ??= DateTime.Now;
|
||||||
if (contract.ContractStatus == TaskContractStatus.PendingGenerate)
|
if (contract.ContractStatus == TaskContractStatus.PendingGenerate)
|
||||||
contract.ContractStatus = TaskContractStatus.PendingConfirm;
|
contract.ContractStatus = TaskContractStatus.PendingConfirm;
|
||||||
await _db.Updateable(contract).ExecuteCommandAsync();
|
|
||||||
|
await _db.Updateable(contract)
|
||||||
|
.UpdateColumns(item => new { item.ReadAt, item.ContractStatus })
|
||||||
|
.ExecuteCommandAsync();
|
||||||
return fileId;
|
return fileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,27 @@ public class OnboardingPublicContractSourceInput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[IdNotNull(ErrorMessage = "任务合同Id不能为空")]
|
[IdNotNull(ErrorMessage = "任务合同Id不能为空")]
|
||||||
public long TaskContractId { get; set; }
|
public long TaskContractId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前生成文件的版本标识,仅用于区分手机下载缓存,不参与文件权限判断。
|
||||||
|
/// </summary>
|
||||||
|
public long? Version { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 员工端合同准备结果。
|
||||||
|
/// </summary>
|
||||||
|
public class OnboardingPublicContractPrepareOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前已经生成并可下载的系统文件 Id,同时作为客户端下载版本号。
|
||||||
|
/// </summary>
|
||||||
|
public long FileId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 合同文件生成时间;复用现有文件时返回原生成时间。
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? GeneratedAt { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3182,9 +3182,14 @@
|
|||||||
保存候选人固定基础信息并刷新合同变量快照。
|
保存候选人固定基础信息并刷新合同变量快照。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:SimpleAdmin.Application.IOnboardingPublicTaskService.PrepareContract(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
|
<summary>
|
||||||
|
校验合同变量并提前生成候选人的合同 DOCX。
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="M:SimpleAdmin.Application.IOnboardingPublicTaskService.GetContractSourceFileId(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
<member name="M:SimpleAdmin.Application.IOnboardingPublicTaskService.GetContractSourceFileId(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
<summary>
|
<summary>
|
||||||
校验任务归属后返回合同模板源文件 Id。
|
校验任务归属后返回已经准备完成的合同文件 Id。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:SimpleAdmin.Application.IOnboardingPublicTaskService.GetMaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
<member name="M:SimpleAdmin.Application.IOnboardingPublicTaskService.GetMaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
||||||
@@ -3207,9 +3212,14 @@
|
|||||||
保存候选人的固定基础信息并刷新尚未确认的合同变量快照。
|
保存候选人的固定基础信息并刷新尚未确认的合同变量快照。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.PrepareContract(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
|
<summary>
|
||||||
|
根据员工当前已填写信息校验变量并提前生成合同 DOCX。
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.GetContractSourceFileId(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.GetContractSourceFileId(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
<summary>
|
<summary>
|
||||||
根据员工当前已填写信息生成合同预览,并返回已替换变量的 DOCX 文件 Id。
|
返回已经准备完成的合同文件,下载阶段不再执行变量校验和文档生成。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.GetMaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
<member name="M:SimpleAdmin.Application.OnboardingPublicTaskService.GetMaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
||||||
|
|||||||
+14
-2
@@ -36,13 +36,25 @@ public class OnboardingPublicTaskController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载根据当前任务资料动态生成并已替换变量的合同文件。
|
/// 校验合同变量并提前生成候选人的合同文件。
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("prepare-contract")]
|
||||||
|
public async Task<OnboardingPublicContractPrepareOutput> PrepareContract(
|
||||||
|
[FromBody] OnboardingPublicContractSourceInput input)
|
||||||
|
{
|
||||||
|
return await _service.PrepareContract(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载已经准备完成并替换变量的合同文件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpGet("contract-source")]
|
[HttpGet("contract-source")]
|
||||||
|
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public async Task<FileStreamResult> ContractSource([FromQuery] OnboardingPublicContractSourceInput input)
|
public async Task<FileStreamResult> ContractSource([FromQuery] OnboardingPublicContractSourceInput input)
|
||||||
{
|
{
|
||||||
var fileId = await _service.GetContractSourceFileId(input);
|
var fileId = await _service.GetContractSourceFileId(input);
|
||||||
return await _fileService.Download(new BaseIdInput { Id = fileId });
|
return await _fileService.Download(new BaseIdInput { Id = fileId })
|
||||||
|
?? throw Oops.Bah("合同文件不存在,请重新准备合同");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -296,9 +296,14 @@
|
|||||||
保存候选人固定基础信息。
|
保存候选人固定基础信息。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:SimpleAdmin.Web.Core.OnboardingPublicTaskController.PrepareContract(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
|
<summary>
|
||||||
|
校验合同变量并提前生成候选人的合同文件。
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="M:SimpleAdmin.Web.Core.OnboardingPublicTaskController.ContractSource(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
<member name="M:SimpleAdmin.Web.Core.OnboardingPublicTaskController.ContractSource(SimpleAdmin.Application.OnboardingPublicContractSourceInput)">
|
||||||
<summary>
|
<summary>
|
||||||
下载根据当前任务资料动态生成并已替换变量的合同文件。
|
下载已经准备完成并替换变量的合同文件。
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:SimpleAdmin.Web.Core.OnboardingPublicTaskController.MaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
<member name="M:SimpleAdmin.Web.Core.OnboardingPublicTaskController.MaterialSource(SimpleAdmin.Application.OnboardingPublicMaterialSourceInput)">
|
||||||
|
|||||||
Reference in New Issue
Block a user