using AutoMapper;
using EyeSoft.Messanging;
using MathNet.Numerics;
using OASystem.Domain.Dtos.PersonnelModule;
using OASystem.Domain.Entities.PersonnelModule;
using OASystem.Domain.ViewModels.PersonnelModule;
using OASystem.Domain.ViewModels.QiYeWeChat;
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<(bool Success, string Message, List Departments, List DepartmentsWithJobs)>
KpiDepartmentsAndJobs(string depName = "")
{
var departments = new List();
var departmentsWithJobs = new List();
var config = await _sqlSugar.Queryable()
.Where(x => x.IsDel == 0 && x.Id == 132)
.FirstAsync();
if (config == null) return (false, "配置为空", departments, departmentsWithJobs);
var typeIds = JsonSerializer.Deserialize>(config.Remark ?? "[]");
if (typeIds == null || typeIds.Count < 1)
return (false, "类型ID为空", departments, departmentsWithJobs);
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 != "未分类")
.WhereIF(!string.IsNullOrEmpty(depName),x=> x.Department.Equals(depName))
.GroupBy(x => x.Department)
.Select(g => new KpiTempDepartmentInfo()
{
DepName = g.Key,
JobNames = g.Select(x => x.Job).Distinct().Where(j => j != "通用").OrderBy(j => j).ToList()
})
.OrderBy(g => g.DepName)
.ToList();
departmentsWithJobs = deptJobList;
departments = deptJobList.Select(g => g.DepName).ToList();
return (true, "操作成功", departments, departmentsWithJobs);
}
///
/// 基础数据
///
///
public async Task InitAsync()
{
var result = await KpiDepartmentsAndJobs("财务部");
if (!result.Success)
{
_jv.Msg = result.Message;
return _jv;
}
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();
var jobNames = result.DepartmentsWithJobs
.SelectMany(x => x.JobNames)
.ToList();
var view = userInfos.Where(x => jobNames.Contains(x.JobName))
.Select(x => new KpiTempUserInfo() { Id = x.UserId, DepName = x.DepName, JobName = x.JobName, Name = x.UserName })
.ToList();
_jv.Code = StatusCodes.Status200OK;
_jv.Data = view;
_jv.Msg = $"操作成功";
return _jv;
}
///
/// 考勤详情
///
/// 月份 2025-12
/// 考核人
///
public async Task InfoAsync(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, u) => cdk.Evaluator == u.Id)
.Where((cdk, u) => cdk.IsDel == 0 && cdk.Evaluator == evaluator && cdk.Month.Equals(month))
.Select((cdk, u) => new CompanyDailyKpiView()
{
Id = cdk.Id,
Month = cdk.Month,
EvalContentOrder = cdk.EvalContentOrder,
Evaluator = cdk.Evaluator,
EvaluatorName = u.CnName,
EvalContent = cdk.EvalContent,
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 =>
{
_ = int.TryParse(c.KpiSort, out int no);
info.Add(new CompanyDailyKpiView()
{
Month = month,
EvalContentOrder = no,
Evaluator = evaluatorInfo.UserId,
EvaluatorName = evaluatorInfo.UserName,
EvalContent = c.KpiContent,
IsMistake = false,
MistakeReason = string.Empty
});
});
});
}
_jv.Code = StatusCodes.Status200OK;
_jv.Data = info;
_jv.Msg = $"操作成功";
return _jv;
}
///
/// kpi Save
///
/// 请求类
///
public async Task SaveAsync(CompanyDailyKpiSaveDto dto)
{
if (dto.Infos == null || !dto.Infos.Any())
{
_jv.Msg = $"请选择需要新增或者编辑的数据!";
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 == dto.CurrUserId)
.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;
}
_ = dto.Infos.OrderBy(x => x.EvalContentOrder);
var infos = _mapper.Map>(dto.Infos);
infos.ForEach(x => {
if (x.Id <= 0)
{
x.CreateUserId = dto.CurrUserId;
}
x.LastUpdateUserId = dto.CurrUserId;
x.LastUpdateTime = DateTime.Now;
});
try
{
var storage = _sqlSugar.Storageable(infos)
.WhereColumns(x => x.Id) // 根据Id判断
.ToStorage();
await storage.AsInsertable.ExecuteCommandAsync();
await storage.AsUpdateable.ExecuteCommandAsync();
_jv.Code = StatusCodes.Status200OK;
//_jv.Data = infos;
_jv.Msg = $"操作成功";
return _jv;
}
catch (Exception ex)
{
_jv.Msg = $"操作失败!Ex:{ex.Message}";
return _jv;
}
}
}
}