Files
OnboardXAdmin/SimpleAdmin.Application/Services/Onboarding/Department/OnboardingDepartmentService.cs
T
2026-09-09 14:57:41 +08:00

177 lines
7.2 KiB
C#

namespace SimpleAdmin.Application;
/// <summary>
/// 实现入职业务部门业务能力。
/// </summary>
public class OnboardingDepartmentService : DbRepository<ObDepartment>, IOnboardingDepartmentService
{
/// <summary>
/// 分页查询入职业务部门。
/// </summary>
public async Task<SqlSugarPagedList<ObDepartment>> Page(OnboardingDepartmentPageInput input)
{
var list = await Context.Queryable<ObDepartment>()
.WhereIF(input.CompanyId.HasValue, it => it.CompanyId == input.CompanyId.Value)
.WhereIF(!string.IsNullOrWhiteSpace(input.DepartmentCode), it => it.DepartmentCode.Contains(input.DepartmentCode))
.WhereIF(!string.IsNullOrWhiteSpace(input.DepartmentName), it => it.DepartmentName.Contains(input.DepartmentName))
.WhereIF(!string.IsNullOrWhiteSpace(input.Status), it => it.Status == input.Status)
.OrderByIF(!string.IsNullOrWhiteSpace(input.SortField), $"{input.SortField} {input.SortOrder}")
.OrderBy(it => it.SortCode)
.OrderBy(it => it.DepartmentName)
.ToPagedListAsync(input.PageNum, input.PageSize);
if (list.List != null && list.List.Any())
{
var companyIds = list.List.Select(d => d.CompanyId).Distinct().ToList();
var companies = await Context.Queryable<ObCompany>()
.Where(c => companyIds.Contains(c.Id))
.ToListAsync();
var companyMap = companies.ToDictionary(c => c.Id, c => c.CompanyName);
foreach (var item in list.List)
{
if (companyMap.TryGetValue(item.CompanyId, out var cName))
{
item.CompanyName = cName;
}
}
}
return list;
}
/// <summary>
/// 查询指定公司下全部已启用部门列表。
/// </summary>
public Task<List<ObDepartment>> ListEnabled(long companyId)
{
return Context.Queryable<ObDepartment>()
.Where(it => it.CompanyId == companyId && it.Status == "enable")
.OrderBy(it => it.SortCode)
.OrderBy(it => it.DepartmentName)
.ToListAsync();
}
/// <summary>
/// 查询部门详情。
/// </summary>
public async Task<ObDepartment> Detail(BaseIdInput input)
{
return await GetByIdAsync(input.Id) ?? throw Oops.Bah("部门不存在");
}
/// <summary>
/// 新增入职业务部门。
/// </summary>
public async Task Add(OnboardingDepartmentAddInput input)
{
NormalizeInput(input);
await EnsureCompanyExists(input.CompanyId);
await EnsureCodeUnique(input.CompanyId, input.DepartmentCode, 0);
await InsertAsync(input.Adapt<ObDepartment>());
}
/// <summary>
/// 编辑入职业务部门。
/// </summary>
public async Task Edit(OnboardingDepartmentEditInput input)
{
NormalizeInput(input);
var department = await Detail(new BaseIdInput { Id = input.Id });
await EnsureCompanyCanChange(department, input.CompanyId);
await EnsureCompanyExists(input.CompanyId);
await EnsureCodeUnique(input.CompanyId, input.DepartmentCode, input.Id);
await UpdateAsync(input.Adapt<ObDepartment>());
}
/// <summary>
/// 删除未被岗位或任务引用的部门。
/// </summary>
public async Task Delete(BaseIdListInput input)
{
if (input.Ids.Count == 0)
return;
var hasPositions = await Context.Queryable<ObPosition>()
.AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value));
if (hasPositions)
throw Oops.Bah("部门下已有岗位,不能删除");
var hasTasks = await Context.Queryable<ObOnboardingTask>()
.AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value));
if (hasTasks)
throw Oops.Bah("部门已有入职任务,不能删除");
var hasEmployees = await Context.Queryable<ObEmployee>()
.AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value));
if (hasEmployees)
throw Oops.Bah("部门已有正式员工,不能删除");
var hasOnboardingTemplates = await Context.Queryable<ObOnboardingTemplate>()
.AnyAsync(item => item.DepartmentId.HasValue && input.Ids.Contains(item.DepartmentId.Value));
if (hasOnboardingTemplates)
throw Oops.Bah("部门已被入职模板引用,不能删除");
var hasContractTemplates = await Context.Queryable<ObContractTemplate>()
.AnyAsync(item => item.DepartmentId.HasValue && input.Ids.Contains(item.DepartmentId.Value));
if (hasContractTemplates)
throw Oops.Bah("部门已被合同模板引用,不能删除");
await DeleteByIdsAsync(input.Ids.Cast<object>().ToArray());
}
private async Task EnsureCompanyExists(long companyId)
{
var exists = await Context.Queryable<ObCompany>()
.AnyAsync(it => it.Id == companyId && it.Status == "enable");
if (!exists)
throw Oops.Bah("所属公司不存在、已删除或未启用");
}
/// <summary>
/// 标准化部门输入并拒绝非法状态。
/// </summary>
private static void NormalizeInput(OnboardingDepartmentAddInput input)
{
input.DepartmentCode = OnboardingCodeValidator.Normalize(input.DepartmentCode, "部门编码", 50);
input.DepartmentName = input.DepartmentName?.Trim();
if (string.IsNullOrWhiteSpace(input.DepartmentName))
{
throw Oops.Bah("请填写部门名称");
}
if (input.Status != "enable" && input.Status != "disable")
throw Oops.Bah("部门状态不正确");
}
/// <summary>
/// 已产生下级或业务引用的部门不允许直接变更所属公司。
/// </summary>
private async Task EnsureCompanyCanChange(ObDepartment department, long companyId)
{
if (department.CompanyId == companyId)
return;
var hasPosition = await Context.Queryable<ObPosition>()
.AnyAsync(item => item.DepartmentId == department.Id);
var hasTask = await Context.Queryable<ObOnboardingTask>()
.AnyAsync(item => item.DepartmentId == department.Id);
var hasEmployee = await Context.Queryable<ObEmployee>()
.AnyAsync(item => item.DepartmentId == department.Id);
var hasOnboardingTemplate = await Context.Queryable<ObOnboardingTemplate>()
.AnyAsync(item => item.DepartmentId == department.Id);
var hasContractTemplate = await Context.Queryable<ObContractTemplate>()
.AnyAsync(item => item.DepartmentId == department.Id);
if (hasPosition || hasTask || hasEmployee || hasOnboardingTemplate || hasContractTemplate)
throw Oops.Bah("部门已有岗位、模板、任务或员工引用,不能直接变更所属公司");
}
private async Task EnsureCodeUnique(long companyId, string code, long id)
{
var exists = await Context.Queryable<ObDepartment>()
.AnyAsync(it => it.CompanyId == companyId && it.DepartmentCode == code && it.Id != id);
if (exists)
throw Oops.Bah("该公司下部门编码已存在");
}
}