namespace SimpleAdmin.Application; /// /// 实现入职业务部门业务能力。 /// public class OnboardingDepartmentService : DbRepository, IOnboardingDepartmentService { private readonly IOnboardingDataPermissionService _dataPermission; public OnboardingDepartmentService(IOnboardingDataPermissionService dataPermission) { _dataPermission = dataPermission; } /// /// 分页查询入职业务部门。 /// public async Task> Page(OnboardingDepartmentPageInput input) { var list = await Context.Queryable() .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.GetSafeOrderBy("Id", "Status", "CreateTime", "UpdateTime", "CreateUser", "CreateUserId", "CompanyId", "DepartmentCode", "DepartmentName", "SortCode")) .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() .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; } /// /// 查询指定公司下全部已启用部门列表。 /// public Task> ListEnabled(long companyId) { return Context.Queryable() .Where(it => it.CompanyId == companyId && it.Status == "enable") .OrderBy(it => it.SortCode) .OrderBy(it => it.DepartmentName) .ToListAsync(); } /// /// 查询部门详情。 /// public async Task Detail(BaseIdInput input) { return await GetByIdAsync(input.Id) ?? throw Oops.Bah("部门不存在"); } /// /// 新增入职业务部门。 /// public async Task Add(OnboardingDepartmentAddInput input) { NormalizeInput(input); await EnsureCompanyExists(input.CompanyId); await EnsureCodeUnique(input.CompanyId, input.DepartmentCode, 0); await InsertAsync(input.Adapt()); } /// /// 编辑入职业务部门。 /// public async Task Edit(OnboardingDepartmentEditInput input) { NormalizeInput(input); var department = await Detail(new BaseIdInput { Id = input.Id }); await _dataPermission.EnsureCanManage( department.CreateUserId, OnboardingPermissionCodes.SetupManageAll, "部门"); await EnsureCompanyCanChange(department, input.CompanyId); await EnsureCompanyExists(input.CompanyId); await EnsureCodeUnique(input.CompanyId, input.DepartmentCode, input.Id); await UpdateAsync(input.Adapt()); } /// /// 删除未被岗位或任务引用的部门。 /// public async Task Delete(BaseIdListInput input) { if (input.Ids.Count == 0) return; var departments = await Context.Queryable() .Where(item => input.Ids.Contains(item.Id)) .ToListAsync(); if (departments.Count != input.Ids.Distinct().Count()) throw Oops.Bah("部门不存在"); await _dataPermission.EnsureCanManage( departments.Select(item => item.CreateUserId), OnboardingPermissionCodes.SetupManageAll, "部门"); var hasPositions = await Context.Queryable() .AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value)); if (hasPositions) throw Oops.Bah("部门下已有岗位,不能删除"); var hasTasks = await Context.Queryable() .AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value)); if (hasTasks) throw Oops.Bah("部门已有入职任务,不能删除"); var hasEmployees = await Context.Queryable() .AnyAsync(it => it.DepartmentId.HasValue && input.Ids.Contains(it.DepartmentId.Value)); if (hasEmployees) throw Oops.Bah("部门已有正式员工,不能删除"); var hasOnboardingTemplates = await Context.Queryable() .AnyAsync(item => item.DepartmentId.HasValue && input.Ids.Contains(item.DepartmentId.Value)); if (hasOnboardingTemplates) throw Oops.Bah("部门已被入职模板引用,不能删除"); var hasContractTemplates = await Context.Queryable() .AnyAsync(item => item.DepartmentId.HasValue && input.Ids.Contains(item.DepartmentId.Value)); if (hasContractTemplates) throw Oops.Bah("部门已被合同模板引用,不能删除"); await DeleteByIdsAsync(input.Ids.Cast().ToArray()); } private async Task EnsureCompanyExists(long companyId) { var exists = await Context.Queryable() .AnyAsync(it => it.Id == companyId && it.Status == "enable"); if (!exists) throw Oops.Bah("所属公司不存在、已删除或未启用"); } /// /// 标准化部门输入并拒绝非法状态。 /// 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("部门状态不正确"); } /// /// 已产生下级或业务引用的部门不允许直接变更所属公司。 /// private async Task EnsureCompanyCanChange(ObDepartment department, long companyId) { if (department.CompanyId == companyId) return; var hasPosition = await Context.Queryable() .AnyAsync(item => item.DepartmentId == department.Id); var hasTask = await Context.Queryable() .AnyAsync(item => item.DepartmentId == department.Id); var hasEmployee = await Context.Queryable() .AnyAsync(item => item.DepartmentId == department.Id); var hasOnboardingTemplate = await Context.Queryable() .AnyAsync(item => item.DepartmentId == department.Id); var hasContractTemplate = await Context.Queryable() .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() .AnyAsync(it => it.CompanyId == companyId && it.DepartmentCode == code && it.Id != id); if (exists) throw Oops.Bah("该公司下部门编码已存在"); } }