134 lines
5.2 KiB
C#
134 lines
5.2 KiB
C#
namespace SimpleAdmin.Application;
|
|
|
|
/// <summary>
|
|
/// 实现入职任务创建业务能力。
|
|
/// </summary>
|
|
public class OnboardingTaskService : IOnboardingTaskService
|
|
{
|
|
private readonly SqlSugarScope _db;
|
|
private readonly IConfigService _configService;
|
|
private readonly IOnboardingContractSnapshotService _snapshotService;
|
|
|
|
public OnboardingTaskService(
|
|
IConfigService configService,
|
|
IOnboardingContractSnapshotService snapshotService)
|
|
{
|
|
_db = DbContext.DB;
|
|
_configService = configService;
|
|
_snapshotService = snapshotService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 校验公司、岗位和合同范围后创建入职任务、链接及任务合同。
|
|
/// </summary>
|
|
public async Task<OnboardingTaskCreatedOutput> Create(OnboardingTaskCreateInput input)
|
|
{
|
|
var companyEnabled = await _db.Queryable<ObCompany>()
|
|
.AnyAsync(item => item.Id == input.CompanyId && item.Status == "enable");
|
|
if (!companyEnabled)
|
|
{
|
|
throw Oops.Bah("公司不存在或未启用");
|
|
}
|
|
|
|
var positionEnabled = await _db.Queryable<ObPosition>()
|
|
.AnyAsync(item => item.Id == input.PositionId
|
|
&& item.CompanyId == input.CompanyId
|
|
&& item.Status == "enable");
|
|
if (!positionEnabled)
|
|
{
|
|
throw Oops.Bah("岗位不存在、未启用或不属于该公司");
|
|
}
|
|
|
|
var scopes = await _db.Queryable<ObContractScope>()
|
|
.Where(item => item.CompanyId == input.CompanyId
|
|
&& (item.PositionId == null || item.PositionId == input.PositionId))
|
|
.ToListAsync();
|
|
|
|
// 同一版本同时存在“全公司”和“指定岗位”范围时,岗位专属配置优先,避免同一合同生成两次。
|
|
scopes = scopes
|
|
.GroupBy(item => item.TemplateVersionId)
|
|
.Select(group => group.FirstOrDefault(item => item.PositionId == input.PositionId) ?? group.First())
|
|
.ToList();
|
|
if (scopes.Count == 0)
|
|
{
|
|
throw Oops.Bah("该公司和岗位尚未配置合同适用范围");
|
|
}
|
|
|
|
var taskId = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId();
|
|
var expiryConfig = await _configService.GetByConfigKey(
|
|
CateGoryConst.CONFIG_BIZ_DEFINE,
|
|
"onboard.link.expireHours");
|
|
if (expiryConfig == null
|
|
|| !int.TryParse(expiryConfig.ConfigValue, out var expiryHours)
|
|
|| expiryHours <= 0)
|
|
{
|
|
throw Oops.Bah("请在系统配置中设置 onboard.link.expireHours(正整数小时)");
|
|
}
|
|
|
|
var expiresAt = DateTime.Now.AddHours(expiryHours);
|
|
var token = Guid.NewGuid().ToString("N");
|
|
var task = new ObOnboardingTask
|
|
{
|
|
Id = taskId,
|
|
TaskNo = $"OB{DateTime.Now:yyyyMMddHHmmss}{taskId.ToString()[^4..]}",
|
|
CompanyId = input.CompanyId,
|
|
PositionId = input.PositionId,
|
|
AssignedReviewerUserId = input.AssignedReviewerUserId,
|
|
LinkExpireAt = expiresAt,
|
|
TaskStatus = OnboardingTaskStatus.PendingFill,
|
|
Remark = input.Remark
|
|
};
|
|
|
|
// 任务、链接、合同实例和变量快照属于同一创建动作,必须保证事务一致性。
|
|
await _db.Ado.BeginTranAsync();
|
|
try
|
|
{
|
|
await _db.Insertable(task).ExecuteCommandAsync();
|
|
await _db.Insertable(new ObTaskLink
|
|
{
|
|
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
|
|
TaskId = taskId,
|
|
TokenHash = Convert.ToHexString(global::System.Security.Cryptography.SHA256.HashData(
|
|
global::System.Text.Encoding.UTF8.GetBytes(token))),
|
|
ExpiresAt = expiresAt
|
|
}).ExecuteCommandAsync();
|
|
|
|
var templateIds = scopes.Select(item => item.TemplateId).Distinct().ToList();
|
|
var templates = await _db.Queryable<ObContractTemplate>()
|
|
.Where(item => templateIds.Contains(item.Id))
|
|
.ToListAsync();
|
|
var contracts = scopes.Select(scope =>
|
|
{
|
|
var template = templates.First(item => item.Id == scope.TemplateId);
|
|
return new ObTaskContract
|
|
{
|
|
Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
|
|
TaskId = taskId,
|
|
TemplateId = scope.TemplateId,
|
|
TemplateVersionId = scope.TemplateVersionId,
|
|
ContractName = template.TemplateName,
|
|
ContractType = template.ContractType,
|
|
Required = scope.Required
|
|
};
|
|
}).ToList();
|
|
|
|
await _db.Insertable(contracts).ExecuteCommandAsync();
|
|
await _snapshotService.Build(taskId);
|
|
await _db.Ado.CommitTranAsync();
|
|
}
|
|
catch
|
|
{
|
|
await _db.Ado.RollbackTranAsync();
|
|
throw;
|
|
}
|
|
|
|
return new OnboardingTaskCreatedOutput
|
|
{
|
|
TaskId = taskId,
|
|
TaskNo = task.TaskNo,
|
|
LinkToken = token,
|
|
ExpiresAt = expiresAt
|
|
};
|
|
}
|
|
}
|