1
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
public interface IOnboardingPublicTaskService : ITransient
|
||||
{
|
||||
Task<OnboardingTaskPublicDetailOutput> Detail(OnboardingTaskPublicAccessInput input);
|
||||
Task SaveEmployeeInfo(OnboardingTaskPublicSaveInput input);
|
||||
Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input);
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
namespace SimpleAdmin.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 员工手机端入口;仅凭一次性任务链接访问,绝不创建正式员工。
|
||||
/// </summary>
|
||||
public class OnboardingPublicTaskService : IOnboardingPublicTaskService
|
||||
{
|
||||
private readonly ISqlSugarClient _db;
|
||||
private readonly IOnboardingContractSnapshotService _snapshotService;
|
||||
|
||||
public OnboardingPublicTaskService(
|
||||
ISqlSugarClient db,
|
||||
IOnboardingContractSnapshotService snapshotService)
|
||||
{
|
||||
_db = db;
|
||||
_snapshotService = snapshotService;
|
||||
}
|
||||
|
||||
public async Task<OnboardingTaskPublicDetailOutput> Detail(OnboardingTaskPublicAccessInput input)
|
||||
{
|
||||
var link = await GetActiveLink(input.Token);
|
||||
var task = await _db.Queryable<ObOnboardingTask>().InSingleAsync(link.TaskId)
|
||||
?? throw Oops.Bah("入职任务不存在");
|
||||
|
||||
link.AccessCount++;
|
||||
link.LastAccessedAt = DateTime.Now;
|
||||
await _db.Updateable(link).ExecuteCommandAsync();
|
||||
|
||||
var formRequirements = await GetEffectiveFormRequirements(task);
|
||||
var materialRequirements = await GetEffectiveMaterialRequirements(task);
|
||||
var fields = await _db.Queryable<ObFormField>()
|
||||
.Where(x => formRequirements.Select(r => r.FieldId).Contains(x.Id) && x.Status == "enable")
|
||||
.ToListAsync();
|
||||
var materialTypes = await _db.Queryable<ObMaterialType>()
|
||||
.Where(x => materialRequirements.Select(r => r.MaterialTypeId).Contains(x.Id) && x.Status == "enable")
|
||||
.ToListAsync();
|
||||
|
||||
return new OnboardingTaskPublicDetailOutput
|
||||
{
|
||||
Task = task,
|
||||
EmployeeInfo = await _db.Queryable<ObTaskEmployeeInfo>().FirstAsync(it => it.TaskId == task.Id),
|
||||
Contracts = await _db.Queryable<ObTaskContract>()
|
||||
.Where(it => it.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
DynamicValues = await _db.Queryable<ObTaskFormValue>()
|
||||
.Where(x => x.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
Materials = await _db.Queryable<ObTaskMaterial>()
|
||||
.Where(x => x.TaskId == task.Id)
|
||||
.ToListAsync(),
|
||||
FormFields = formRequirements
|
||||
.OrderBy(x => x.SortCode)
|
||||
.Select(requirement => fields.FirstOrDefault(field => field.Id == requirement.FieldId))
|
||||
.Where(field => field != null)
|
||||
.Select(field => new OnboardingPublicFormFieldOutput
|
||||
{
|
||||
FieldId = field.Id,
|
||||
FieldCode = field.FieldCode,
|
||||
FieldName = field.FieldName,
|
||||
DataType = field.DataType,
|
||||
OptionsJson = field.OptionsJson,
|
||||
Required = formRequirements.First(requirement => requirement.FieldId == field.Id).Required
|
||||
})
|
||||
.ToList(),
|
||||
MaterialRequirements = materialRequirements
|
||||
.OrderBy(x => x.SortCode)
|
||||
.Select(requirement => materialTypes.FirstOrDefault(material => material.Id == requirement.MaterialTypeId))
|
||||
.Where(material => material != null)
|
||||
.Select(material => new OnboardingPublicMaterialOutput
|
||||
{
|
||||
MaterialTypeId = material.Id,
|
||||
MaterialName = material.MaterialName,
|
||||
AllowedExtensions = material.AllowedExtensions,
|
||||
MaxFileCount = material.MaxFileCount,
|
||||
Required = materialRequirements.First(requirement => requirement.MaterialTypeId == material.Id).Required
|
||||
})
|
||||
.ToList()
|
||||
};
|
||||
}
|
||||
|
||||
public async Task SaveEmployeeInfo(OnboardingTaskPublicSaveInput input)
|
||||
{
|
||||
var link = await GetActiveLink(input.Token);
|
||||
var task = await _db.Queryable<ObOnboardingTask>().InSingleAsync(link.TaskId)
|
||||
?? throw Oops.Bah("入职任务不存在");
|
||||
if (task.TaskStatus != OnboardingTaskStatus.PendingFill && task.TaskStatus != OnboardingTaskStatus.Rejected)
|
||||
throw Oops.Bah("当前任务不可编辑");
|
||||
|
||||
var old = await _db.Queryable<ObTaskEmployeeInfo>().FirstAsync(it => it.TaskId == task.Id);
|
||||
var entity = input.Adapt<ObTaskEmployeeInfo>();
|
||||
entity.TaskId = task.Id;
|
||||
|
||||
if (old == null)
|
||||
{
|
||||
entity.Id = global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId();
|
||||
await _db.Insertable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.Id = old.Id;
|
||||
await _db.Updateable(entity).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
await _snapshotService.Build(task.Id, entity);
|
||||
}
|
||||
|
||||
public async Task<long> GetContractSourceFileId(OnboardingPublicContractSourceInput input)
|
||||
{
|
||||
var link = await GetActiveLink(input.Token);
|
||||
var contract = await _db.Queryable<ObTaskContract>()
|
||||
.FirstAsync(x => x.Id == input.TaskContractId && x.TaskId == link.TaskId)
|
||||
?? throw Oops.Bah("合同不存在");
|
||||
var version = await _db.Queryable<ObContractTemplateVersion>().InSingleAsync(contract.TemplateVersionId)
|
||||
?? throw Oops.Bah("合同模板版本不存在");
|
||||
|
||||
return version.SourceDocxFileId;
|
||||
}
|
||||
|
||||
private async Task<List<ObFormRequirement>> GetEffectiveFormRequirements(ObOnboardingTask task)
|
||||
{
|
||||
var requirements = await _db.Queryable<ObFormRequirement>()
|
||||
.Where(x => x.CompanyId == task.CompanyId && (x.PositionId == null || x.PositionId == task.PositionId))
|
||||
.ToListAsync();
|
||||
|
||||
return requirements
|
||||
.GroupBy(x => x.FieldId)
|
||||
.Select(group => group.FirstOrDefault(x => x.PositionId == task.PositionId) ?? group.First())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task<List<ObMaterialRequirement>> GetEffectiveMaterialRequirements(ObOnboardingTask task)
|
||||
{
|
||||
var requirements = await _db.Queryable<ObMaterialRequirement>()
|
||||
.Where(x => x.CompanyId == task.CompanyId && (x.PositionId == null || x.PositionId == task.PositionId))
|
||||
.ToListAsync();
|
||||
|
||||
return requirements
|
||||
.GroupBy(x => x.MaterialTypeId)
|
||||
.Select(group => group.FirstOrDefault(x => x.PositionId == task.PositionId) ?? group.First())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task<ObTaskLink> GetActiveLink(string token)
|
||||
{
|
||||
var hash = Convert.ToHexString(
|
||||
global::System.Security.Cryptography.SHA256.HashData(
|
||||
global::System.Text.Encoding.UTF8.GetBytes(token)));
|
||||
var link = await _db.Queryable<ObTaskLink>().FirstAsync(it => it.TokenHash == hash)
|
||||
?? throw Oops.Bah("链接不存在");
|
||||
|
||||
if (link.LinkStatus != OnboardingLinkStatus.Active || link.ExpiresAt <= DateTime.Now)
|
||||
throw Oops.Bah("链接已失效");
|
||||
|
||||
return link;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user