| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- using AutoMapper;
- using OASystem.Domain.Entities.PersonnelModule;
- using OASystem.Domain.ViewModels.PersonnelModule;
- using OASystem.Infrastructure.Repositories.System;
- namespace OASystem.Infrastructure.Repositories.PersonnelModule
- {
- /// <summary>
- /// 公司日常KPI考核仓储
- /// </summary>
- public class CompanyDailyKpiRepository : BaseRepository<Pm_CompanyDailyKpi, Pm_CompanyDailyKpi>
- {
- 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 = "操作失败!" };
- }
- /// <summary>
- /// 绩效模板数据(保持原方法签名)
- /// </summary>
- public async Task<(bool isSuccess, string msg, List<KpiTempTypeInfo> data)> KpiTemplateDataAsync(string depName, string jobName)
- {
- var result = new List<KpiTempTypeInfo>();
- // 获取配置
- var config = await _sqlSugar.Queryable<Sys_SetDataType>()
- .Where(x => x.IsDel == 0 && x.Id == 132)
- .FirstAsync();
- if (config?.Remark == null)
- return (false, "绩效考核-数据类型ID存储为空", result);
- var typeIds = JsonSerializer.Deserialize<List<int>>(config.Remark);
- if (typeIds?.Any() != true)
- return (false, "绩效考核-数据类型ID存储为空", result);
- // 构建查询
- var query = _sqlSugar.Queryable<Sys_SetData>()
- .LeftJoin<Sys_SetDataType>((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);
- }
- /// <summary>
- /// 获取部门和岗位
- /// </summary>
- public async Task<object> KpiDepartmentsAndJobs()
- {
- var config = await _sqlSugar.Queryable<Sys_SetDataType>()
- .Where(x => x.IsDel == 0 && x.Id == 132)
- .FirstAsync();
- if (config == null) return new { Success = false, Message = "配置为空" };
- var typeIds = JsonSerializer.Deserialize<List<int>>(config.Remark ?? "[]");
- if (typeIds == null || typeIds.Count < 1)
- return new { Success = false, Message = "类型ID为空" };
- var names = await _sqlSugar.Queryable<Sys_SetData>()
- .LeftJoin<Sys_SetDataType>((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 财务部日常绩效
- /// <summary>
- /// 基础数据
- /// </summary>
- /// <returns></returns>
- public async Task<JsonView> FinanceInit()
- {
- var userInfos = await _sqlSugar.Queryable<Sys_Users>()
- .LeftJoin<Sys_JobPost>((u, jp) => u.JobPostId == jp.Id)
- .LeftJoin<Sys_Department>((u, jp, d) => u.DepId == d.Id)
- .LeftJoin<Sys_Company>((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;
- }
- /// <summary>
- /// 日常考勤详情
- /// </summary>
- /// <param name="month">月份 2025-12</param>
- /// <param name="userId">考核人</param>
- /// <returns></returns>
- public async Task<JsonView> 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<Sys_Users>()
- .LeftJoin<Sys_Company>((u, c) => u.CompanyId == c.Id)
- .LeftJoin<Sys_Department>((u, c, d) => u.DepId == d.Id)
- .LeftJoin<Sys_JobPost>((u, c, d, jp) => u.JobPostId == d.Id)
- .Where((u, c, d, jp) => u.IsDel == 0)
- .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<Pm_CompanyDailyKpi>()
- .LeftJoin<Sys_SetData>((cdk, sd) => cdk.EvalContent == sd.Id)
- .LeftJoin<Sys_Users>((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,
- 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
- }
- }
|