Files
OnboardXAdmin/SimpleAdmin.Application/Services/Onboarding/EntryConfig/OnboardingEntryConfigService.cs
T
2026-08-24 16:36:47 +08:00

307 lines
10 KiB
C#

namespace SimpleAdmin.Application;
/// <summary>
/// 维护员工端动态字段、材料类型及公司岗位要求。
/// </summary>
public class OnboardingEntryConfigService : IOnboardingEntryConfigService
{
private readonly SqlSugarScope _db;
public OnboardingEntryConfigService()
{
_db = DbContext.DB;
}
/// <summary>
/// 查询全部动态入职字段。
/// </summary>
public Task<List<ObFormField>> ListFormFields()
{
return _db.Queryable<ObFormField>()
.OrderBy(x => x.FieldCode)
.ToListAsync();
}
/// <summary>
/// 新增或编辑动态入职字段。
/// </summary>
public async Task SaveFormField(OnboardingFormFieldSaveInput input)
{
var fieldCodeQuery = _db.Queryable<ObFormField>()
.Where(x => x.FieldCode == input.FieldCode);
if (input.Id.HasValue)
fieldCodeQuery = fieldCodeQuery.Where(x => x.Id != input.Id.Value);
var fieldCodeExists = await fieldCodeQuery.AnyAsync();
if (fieldCodeExists)
throw Oops.Bah("字段编码已存在");
var entity = new ObFormField
{
Id = input.Id ?? global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
FieldCode = input.FieldCode,
FieldName = input.FieldName,
DataType = input.DataType,
OptionsJson = NormalizeOptionsJson(input.OptionsJson),
ValidationRule = input.ValidationRule,
Placeholder = input.Placeholder,
Status = input.Status
};
if (input.Id.HasValue)
{
var exists = await _db.Queryable<ObFormField>().AnyAsync(x => x.Id == input.Id.Value);
if (!exists)
throw Oops.Bah("字段不存在");
await _db.Updateable(entity).ExecuteCommandAsync();
return;
}
await _db.Insertable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 将空白的可选项转换为 null,避免 MySQL JSON 字段写入空字符串时报错。
/// </summary>
private static string NormalizeOptionsJson(string optionsJson)
{
if (string.IsNullOrWhiteSpace(optionsJson))
return null;
var normalizedJson = optionsJson.Trim();
try
{
using var jsonDocument = global::System.Text.Json.JsonDocument.Parse(normalizedJson);
return normalizedJson;
}
catch (global::System.Text.Json.JsonException)
{
throw Oops.Bah("可选项不是有效的 JSON 格式");
}
}
/// <summary>
/// 删除未被填写要求引用的动态字段。
/// </summary>
public async Task DeleteFormFields(BaseIdListInput input)
{
if (input.Ids.Count == 0)
return;
var isReferenced = await _db.Queryable<ObFormRequirement>()
.AnyAsync(x => input.Ids.Contains(x.FieldId));
if (isReferenced)
throw Oops.Bah("字段已被填写要求引用,不能删除");
await _db.Deleteable<ObFormField>().In(input.Ids).ExecuteCommandAsync();
}
/// <summary>
/// 查询全部入职材料类型。
/// </summary>
public Task<List<ObMaterialType>> ListMaterialTypes()
{
return _db.Queryable<ObMaterialType>()
.OrderBy(x => x.MaterialCode)
.ToListAsync();
}
/// <summary>
/// 新增或编辑入职材料类型。
/// </summary>
public async Task SaveMaterialType(OnboardingMaterialTypeSaveInput input)
{
if (input.MaxFileCount <= 0)
throw Oops.Bah("最大文件数量必须大于0");
var materialCodeExists = await _db.Queryable<ObMaterialType>()
.AnyAsync(x => x.MaterialCode == input.MaterialCode && x.Id != input.Id);
if (materialCodeExists)
throw Oops.Bah("资料编码已存在");
var entity = new ObMaterialType
{
Id = input.Id ?? global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
MaterialCode = input.MaterialCode,
MaterialName = input.MaterialName,
AllowedExtensions = input.AllowedExtensions,
MaxFileCount = input.MaxFileCount,
MaxFileSizeMb = input.MaxFileSizeMb,
Status = input.Status
};
if (input.Id.HasValue)
{
var exists = await _db.Queryable<ObMaterialType>().AnyAsync(x => x.Id == input.Id.Value);
if (!exists)
throw Oops.Bah("资料类型不存在");
await _db.Updateable(entity).ExecuteCommandAsync();
return;
}
await _db.Insertable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 删除未被要求或上传记录引用的材料类型。
/// </summary>
public async Task DeleteMaterialTypes(BaseIdListInput input)
{
if (input.Ids.Count == 0)
return;
var isReferenced = await _db.Queryable<ObMaterialRequirement>()
.AnyAsync(x => input.Ids.Contains(x.MaterialTypeId));
if (isReferenced)
throw Oops.Bah("资料类型已被资料要求引用,不能删除");
var hasUploads = await _db.Queryable<ObTaskMaterial>()
.AnyAsync(x => input.Ids.Contains(x.MaterialTypeId));
if (hasUploads)
throw Oops.Bah("资料类型已有上传记录,不能删除");
await _db.Deleteable<ObMaterialType>().In(input.Ids).ExecuteCommandAsync();
}
/// <summary>
/// 查询指定公司的动态字段填写要求。
/// </summary>
public Task<List<ObFormRequirement>> ListFormRequirements(long companyId)
{
return _db.Queryable<ObFormRequirement>()
.Where(x => x.CompanyId == companyId)
.OrderBy(x => x.SortCode)
.ToListAsync();
}
/// <summary>
/// 新增或编辑公司岗位动态字段要求。
/// </summary>
public async Task SaveFormRequirement(OnboardingFormRequirementSaveInput input)
{
await EnsureCompanyAndPosition(input.CompanyId, input.PositionId);
var fieldExists = await _db.Queryable<ObFormField>()
.AnyAsync(x => x.Id == input.FieldId && x.Status == "enable");
if (!fieldExists)
throw Oops.Bah("动态字段不存在或未启用");
var requirementExists = await _db.Queryable<ObFormRequirement>()
.AnyAsync(x => x.CompanyId == input.CompanyId
&& x.PositionId == input.PositionId
&& x.FieldId == input.FieldId
&& x.Id != input.Id);
if (requirementExists)
throw Oops.Bah("该公司、岗位和字段的要求已存在");
var entity = new ObFormRequirement
{
Id = input.Id ?? global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
CompanyId = input.CompanyId,
PositionId = input.PositionId,
FieldId = input.FieldId,
Required = input.Required,
SortCode = input.SortCode
};
if (input.Id.HasValue)
{
await _db.Updateable(entity).ExecuteCommandAsync();
return;
}
await _db.Insertable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 删除动态字段填写要求。
/// </summary>
public Task DeleteFormRequirements(BaseIdListInput input)
{
if (input.Ids.Count == 0)
return Task.CompletedTask;
return _db.Deleteable<ObFormRequirement>().In(input.Ids).ExecuteCommandAsync();
}
/// <summary>
/// 查询指定公司的材料上传要求。
/// </summary>
public Task<List<ObMaterialRequirement>> ListMaterialRequirements(long companyId)
{
return _db.Queryable<ObMaterialRequirement>()
.Where(x => x.CompanyId == companyId)
.OrderBy(x => x.SortCode)
.ToListAsync();
}
/// <summary>
/// 新增或编辑公司岗位材料要求。
/// </summary>
public async Task SaveMaterialRequirement(OnboardingMaterialRequirementSaveInput input)
{
await EnsureCompanyAndPosition(input.CompanyId, input.PositionId);
var materialTypeExists = await _db.Queryable<ObMaterialType>()
.AnyAsync(x => x.Id == input.MaterialTypeId && x.Status == "enable");
if (!materialTypeExists)
throw Oops.Bah("资料类型不存在或未启用");
var requirementExists = await _db.Queryable<ObMaterialRequirement>()
.AnyAsync(x => x.CompanyId == input.CompanyId
&& x.PositionId == input.PositionId
&& x.MaterialTypeId == input.MaterialTypeId
&& x.Id != input.Id);
if (requirementExists)
throw Oops.Bah("该公司、岗位和资料类型的要求已存在");
var entity = new ObMaterialRequirement
{
Id = input.Id ?? global::SimpleAdmin.Core.Utils.CommonUtils.GetSingleId(),
CompanyId = input.CompanyId,
PositionId = input.PositionId,
MaterialTypeId = input.MaterialTypeId,
Required = input.Required,
SortCode = input.SortCode
};
if (input.Id.HasValue)
{
await _db.Updateable(entity).ExecuteCommandAsync();
return;
}
await _db.Insertable(entity).ExecuteCommandAsync();
}
/// <summary>
/// 删除材料上传要求。
/// </summary>
public Task DeleteMaterialRequirements(BaseIdListInput input)
{
if (input.Ids.Count == 0)
return Task.CompletedTask;
return _db.Deleteable<ObMaterialRequirement>().In(input.Ids).ExecuteCommandAsync();
}
private async Task EnsureCompanyAndPosition(long companyId, long? positionId)
{
var companyExists = await _db.Queryable<ObCompany>()
.AnyAsync(x => x.Id == companyId && x.Status == "enable");
if (!companyExists)
throw Oops.Bah("公司不存在或未启用");
if (!positionId.HasValue)
return;
var positionExists = await _db.Queryable<ObPosition>()
.AnyAsync(x => x.Id == positionId.Value && x.CompanyId == companyId && x.Status == "enable");
if (!positionExists)
throw Oops.Bah("岗位不存在、未启用或不属于该公司");
}
}