This commit is contained in:
fuenmao
2026-08-26 15:30:31 +08:00
parent 9ae5e0bc54
commit db3d58bc99
16 changed files with 565 additions and 39 deletions
@@ -38,6 +38,36 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
var contracts = await _db.Queryable<ObTaskContract>()
.Where(item => item.TaskId == task.Id)
.ToListAsync();
var materials = await _db.Queryable<ObTaskMaterial>()
.Where(item => item.TaskId == task.Id)
.ToListAsync();
var materialFileIds = materials
.Select(item => item.FileId)
.Distinct()
.ToList();
var materialFiles = materialFileIds.Count == 0
? new List<SysFile>()
: await _db.Queryable<SysFile>()
.Where(item => materialFileIds.Contains(item.Id))
.ToListAsync();
var materialFileMap = materialFiles.ToDictionary(item => item.Id);
var materialOutputs = materials.Select(item =>
{
materialFileMap.TryGetValue(item.FileId, out var file);
return new OnboardingPublicTaskMaterialOutput
{
Id = item.Id,
MaterialTypeId = item.MaterialTypeId,
MaterialName = item.MaterialName,
FileId = item.FileId,
FileName = file?.Name,
FileSuffix = file?.Suffix,
FileSizeInfo = file?.SizeInfo,
UploadedAt = item.UploadedAt,
ReviewStatus = item.ReviewStatus,
ReviewRemark = item.ReviewRemark
};
}).ToList();
var templateVersionIds = contracts
.Select(item => item.TemplateVersionId)
.Distinct()
@@ -69,9 +99,7 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
.FirstAsync(item => item.TaskId == task.Id),
Contracts = contracts,
DynamicValues = new List<ObTaskFormValue>(),
Materials = await _db.Queryable<ObTaskMaterial>()
.Where(item => item.TaskId == task.Id)
.ToListAsync(),
Materials = materialOutputs,
FormFields = new List<OnboardingPublicFormFieldOutput>(),
MaterialRequirements = materialRequirements.Select(requirement => new OnboardingPublicMaterialOutput
{
@@ -79,6 +107,7 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
MaterialName = requirement.MaterialName,
AllowedExtensions = requirement.AllowedExtensions,
MaxFileCount = requirement.MaxFileCount,
MaxFileSizeMb = requirement.MaxFileSizeMb,
Required = requirement.Required
}).ToList(),
ContractVariables = contractVariables
@@ -155,6 +184,34 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
return fileId;
}
/// <summary>
/// 校验一次性链接与材料归属,避免通过文件 Id 越权读取其他任务文件。
/// </summary>
public async Task<OnboardingPublicTaskMaterialOutput> GetMaterialSource(
OnboardingPublicMaterialSourceInput input)
{
var link = await GetActiveLink(input.Token);
var material = await _db.Queryable<ObTaskMaterial>()
.FirstAsync(item => item.Id == input.TaskMaterialId && item.TaskId == link.TaskId)
?? throw Oops.Bah("上传材料不存在");
var file = await _db.Queryable<SysFile>().InSingleAsync(material.FileId)
?? throw Oops.Bah("上传文件不存在");
return new OnboardingPublicTaskMaterialOutput
{
Id = material.Id,
MaterialTypeId = material.MaterialTypeId,
MaterialName = material.MaterialName,
FileId = material.FileId,
FileName = file.Name,
FileSuffix = file.Suffix,
FileSizeInfo = file.SizeInfo,
UploadedAt = material.UploadedAt,
ReviewStatus = material.ReviewStatus,
ReviewRemark = material.ReviewRemark
};
}
private async Task<ObTaskLink> GetActiveLink(string token)
{
if (string.IsNullOrWhiteSpace(token))
@@ -171,4 +228,4 @@ public class OnboardingPublicTaskService : IOnboardingPublicTaskService
return link;
}
}
}