177 lines
7.2 KiB
C#
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("该公司下部门编码已存在");
|
|
}
|
|
}
|