using AutoMapper; using OASystem.Domain.Entities.PersonnelModule; using OASystem.Domain.ViewModels.PersonnelModule; using OASystem.Infrastructure.Repositories.System; namespace OASystem.Infrastructure.Repositories.PersonnelModule { /// /// 公司日常KPI考核仓储 /// public class CompanyDailyKpiRepository : BaseRepository { private readonly IMapper _mapper; private JsonView _jv; public CompanyDailyKpiRepository(SqlSugarClient sqlSugar, IMapper mapper, ApprovalProcessRepository approvalProcessRep) : base(sqlSugar) { _mapper = mapper; _jv = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作失败!" }; } /// /// 绩效模板数据(保持原方法签名) /// public async Task<(bool isSuccess, string msg, List data)> KpiTemplateDataAsync(string depName, string jobName) { var result = new List(); // 获取配置 var config = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == 132) .FirstAsync(); if (config?.Remark == null) return (false, "绩效考核-数据类型ID存储为空", result); var typeIds = JsonSerializer.Deserialize>(config.Remark); if (typeIds?.Any() != true) return (false, "绩效考核-数据类型ID存储为空", result); // 构建查询 var query = _sqlSugar.Queryable() .LeftJoin((sd, sdt) => sd.STid == sdt.Id) .Where((sd, sdt) => sd.IsDel == 0 && typeIds.Contains(sd.STid)); // 条件过滤 if (!string.IsNullOrWhiteSpace(depName)) query = query.Where((sd, sdt) => sdt.Name.Contains(depName)); if (!string.IsNullOrWhiteSpace(jobName)) query = query.Where((sd, sdt) => sdt.Name.Contains(jobName)); // 查询数据 var data = await query .Select((sd, sdt) => new { KpiTypeId = sd.STid, KpiTypeName = sdt.Name, KpiId = sd.Id, KpiContent = sd.Remark, KpiSort = sd.Name }) .ToListAsync(); if (data?.Any() != true) return (false, "绩效考核模板信息为空", result); // 分组处理 result = data .GroupBy(x => new { x.KpiTypeId, x.KpiTypeName }) .Select(g => new KpiTempTypeInfo() { TypeId = g.Key.KpiTypeId, TypeName = g.Key.KpiTypeName, Contents = g .OrderBy(x => int.TryParse(x.KpiSort, out int s) ? s : int.MaxValue) .ThenBy(x => x.KpiSort) .Select(x => new KpiTempContentInfo(x.KpiId, x.KpiContent, x.KpiSort)) .ToList() }) .Where(g => g.Contents.Any()) .OrderBy(g => g.TypeId) .ToList(); return (true, "操作成功", result); } /// /// 获取部门和岗位 /// public async Task KpiDepartmentsAndJobs() { var config = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == 132) .FirstAsync(); if (config == null) return new { Success = false, Message = "配置为空" }; var typeIds = JsonSerializer.Deserialize>(config.Remark ?? "[]"); if (typeIds == null || typeIds.Count < 1) return new { Success = false, Message = "类型ID为空" }; var names = await _sqlSugar.Queryable() .LeftJoin((sd, sdt) => sd.STid == sdt.Id) .Where((sd, sdt) => sd.IsDel == 0 && typeIds.Contains(sd.STid)) .Select((sd, sdt) => sdt.Name) .Distinct() .ToListAsync(); // 解析部门和岗位 var deptJobList = names .Select(name => { var clean = name.Split('(')[0].Trim(); string dept, job; if (clean.Contains(" - ")) { var parts = clean.Split(" - "); dept = parts[0].EndsWith("部") ? parts[0] : parts[0] + "部"; job = parts.Length > 1 ? parts[1] : "通用"; } else if (clean.Contains("-")) { var parts = clean.Split('-'); dept = parts[0].EndsWith("部") ? parts[0] : parts[0] + "部"; job = parts.Length > 1 ? parts[1] : "通用"; } else { dept = clean.EndsWith("部") ? clean : "未分类"; job = clean.EndsWith("部") ? "通用" : clean; } return new { Department = dept, Job = job }; }) .Where(x => x.Department != "未分类") .GroupBy(x => x.Department) .Select(g => new { Department = g.Key, Jobs = g.Select(x => x.Job).Distinct().Where(j => j != "通用").OrderBy(j => j).ToList() }) .OrderBy(g => g.Department) .ToList(); return new { Success = true, Departments = deptJobList.Select(g => g.Department).ToList(), DepartmentsWithJobs = deptJobList }; } #region 财务部日常绩效 /// /// 基础数据 /// /// public async Task FinanceInit() { var userInfos = await _sqlSugar.Queryable() .LeftJoin((u, jp) => u.JobPostId == jp.Id) .LeftJoin((u, jp, d) => u.DepId == d.Id) .LeftJoin((u, jp, d, c) => u.CompanyId == c.Id) .Where((u, jp, d, c) => u.IsDel == 0) .Select((u, jp, d, c) => new { UserId = u.Id, u.CompanyId, c.CompanyName, u.DepId, d.DepName, u.JobPostId, jp.JobName, UserName = u.CnName }) .OrderBy(u => u.CompanyId) .ToListAsync(); if (userInfos?.Any() != true) { _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"暂无人员数据"; return _jv; } //转换为层级结构 #region 层级转换 公司 -> 部门 -> 岗位 -> 人员 //var result = userInfos // .GroupBy(u => new { u.CompanyId, u.CompanyName }) // .Select(companyGroup => new // { // CompanyId = companyGroup.Key.CompanyId, // CompanyName = companyGroup.Key.CompanyName, // Departments = companyGroup // .GroupBy(u => new { u.DepId, u.DepName }) // .Select(departmentGroup => new // { // DepId = departmentGroup.Key.DepId, // DepartmentName = departmentGroup.Key.DepName, // JobPosts = departmentGroup // .GroupBy(u => new { u.JobPostId, u.JobName }) // .Select(jobGroup => new // { // JobPostId = jobGroup.Key.JobPostId, // JobName = jobGroup.Key.JobName, // Employees = jobGroup // .Select(u => new // { // Id = u.UserId, // UserName = u.UserName, // }) // .OrderBy(e => e.UserName) // .ToList() // }) // .OrderBy(j => j.JobName) // .ToList() // }) // .OrderBy(d => d.DepartmentName) // .ToList() // }) // .OrderBy(c => c.CompanyName) // .ToList(); #endregion //转换为层级结构 #region 层级转换 公司 -> 部门 -> 人员 // 构建树形结构 var result = userInfos .GroupBy(u => new { u.CompanyId, u.CompanyName }) .Select(companyGroup => new { CompanyId = companyGroup.Key.CompanyId, CompanyName = companyGroup.Key.CompanyName, Departments = companyGroup .GroupBy(u => new { u.DepId, u.DepName }) .Where(deptGroup => deptGroup.Key.DepId > 0) // 过滤掉无部门的人员 .Select(deptGroup => new { DepartmentId = deptGroup.Key.DepId, DepartmentName = deptGroup.Key.DepName, Users = deptGroup .Select(u => new { u.UserId, u.UserName, u.JobPostId, u.JobName }) .OrderBy(u => u.UserName) .ToList() }) .Where(dept => dept.Users.Any()) .OrderBy(dept => dept.DepartmentName) .ToList(), // 无部门的人员(直接挂载到公司下) NoDepartmentUsers = companyGroup .Where(u => u.DepId <= 0) .Select(u => new { u.UserId, u.UserName, u.JobPostId, u.JobName }) .OrderBy(u => u.UserName) .ToList() }) .OrderBy(c => c.CompanyName) .ToList(); #endregion _jv.Code = StatusCodes.Status200OK; _jv.Data = result; _jv.Msg = $"操作成功"; return _jv; } /// /// 日常考勤详情 /// /// 月份 2025-12 /// 考核人 /// public async Task FinanceInfo(string month, int evaluator) { if (string.IsNullOrEmpty(month)) { _jv.Msg = $"请选择月份!"; return _jv; } // 格式:2025-11 const string pattern = @"^(\d{4})-(0[1-9]|1[0-2])$"; if (!Regex.IsMatch(month, pattern)) { _jv.Msg = $"请选择正确的月份!格式:2025-12"; return _jv; } var evaluatorInfo = await _sqlSugar.Queryable() .LeftJoin((u, c) => u.CompanyId == c.Id) .LeftJoin((u, c, d) => u.DepId == d.Id) .LeftJoin((u, c, d, jp) => u.JobPostId == jp.Id) .Where((u, c, d, jp) => u.IsDel == 0 && u.Id == evaluator) .Select((u, c, d, jp) => new { UserId = u.Id, u.CompanyId, c.CompanyName, u.DepId, d.DepName, u.JobPostId, jp.JobName, UserName = u.CnName }) .FirstAsync(); if (evaluatorInfo == null) { _jv.Msg = $"请选择有效的考核人!"; return _jv; } var info = await _sqlSugar .Queryable() .LeftJoin((cdk, sd) => cdk.EvalContent == sd.Id) .LeftJoin((cdk, sd, u) => cdk.Evaluator == u.Id) .Where((cdk, sd, u) => cdk.IsDel == 0 && cdk.Evaluator == evaluator && cdk.Month.Equals(month)) .Select((cdk, sd, u) => new CompanyDailyKpiView() { Id = cdk.Id, Month = cdk.Month, EvaluatorId = cdk.Evaluator, Evaluator = u.CnName, EvalContentId = cdk.EvalContent, EvalContent = sd.Remark, IsMistake = cdk.IsMistake, MistakeReason = cdk.MistakeReason }) .ToListAsync(); if (!info.Any()) { var tempInfo = await KpiTemplateDataAsync(evaluatorInfo.DepName, evaluatorInfo.JobName); if (!tempInfo.isSuccess) { _jv.Msg = $"{evaluatorInfo.DepName} - {evaluatorInfo.JobName},未配置日常绩效考核。"; return _jv; } tempInfo.data.ForEach(t => { t.Contents.ForEach(c => { info.Add(new CompanyDailyKpiView() { Month = month, No = c.KpiSort, EvaluatorId = evaluatorInfo.UserId, Evaluator = evaluatorInfo.UserName, EvalContentId = c.KpiId, EvalContent = c.KpiContent, IsMistake = false, MistakeReason = string.Empty }); }); }); } _jv.Code = StatusCodes.Status200OK; _jv.Data = info; _jv.Msg = $"操作成功"; return _jv; } #endregion } }