using Furion.DatabaseAccessor.Extensions;
using YBEE.EQM.Core;
namespace YBEE.EQM.Application;
///
/// 缺测替补审核服务
///
public class ExamAbsentReplaceAuditService(IRepository rep, ISysRoleService sysRoleService) : IExamAbsentReplaceAuditService, ITransient
{
///
/// 提交审核
///
///
///
public async Task Submit(BaseId input)
{
var item = await rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
var dtype = await rep.Change().Where(t => t.ExamPlanId == item.ExamPlanId && t.Type == DataReportType.ABSENT_REPLACE).FirstOrDefaultAsync();
if (dtype == null || dtype.Status != ExamStatus.ACTIVE || (item.Status != AuditStatus.UNSUBMIT && item.Status != AuditStatus.REJECTED))
{
throw Oops.Oh(ErrorCode.E2006);
}
item.Status = AuditStatus.AUDIT;
item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(AuditActionType.SUBMIT, item.Status));
await item.UpdateAsync();
}
///
/// 审核
///
///
///
public async Task Audit(ExamAbsentReplaceAuditInput input)
{
var dt = DateTime.Now;
var items = await rep.Where(t => input.Ids.Contains(t.Id)).ToListAsync();
foreach (var item in items)
{
item.Status = input.IsApproved ? AuditStatus.APPROVED : AuditStatus.REJECTED;
item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(input.IsApproved ? AuditActionType.APPROVE : AuditActionType.REJECT, item.Status, dt, input.Remark));
}
await rep.UpdateAsync(items);
}
///
/// 反审
///
///
///
public async Task Reaudit(BaseId input)
{
var item = await rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
if (item.Status != AuditStatus.APPROVED)
{
throw Oops.Oh(ErrorCode.E2006);
}
item.Status = AuditStatus.APPROVE_CANCELED;
item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(AuditActionType.REAUDIT, item.Status));
await item.UpdateAsync();
}
///
/// 获取待审核监测计划列表
///
///
///
public async Task> QueryExamPlanPageList(ExamPlanPageInput input)
{
var roleDataScope = await sysRoleService.GetCurrentUserDataScope();
if (roleDataScope == null || roleDataScope.EducationStages.Count == 0)
{
return new();
}
List whereCause = new();
if (roleDataScope.EducationStages.Count == 0)
{
whereCause.Add($"T1.education_stage = {(short)roleDataScope.EducationStages[0]}");
}
else
{
var ess = roleDataScope.EducationStages.Select(t => $"T1.education_stage = {(short)t}").ToList();
string wes = string.Join(" OR ", ess);
whereCause.Add($"({wes})");
}
if (!string.IsNullOrEmpty(input.Name?.Trim()))
{
whereCause.Add("T1.full_name LIKE '%@name%'");
}
if (input.SemesterId.HasValue)
{
whereCause.Add("T1.semester_id = @semesterId");
}
if (input.Status.HasValue)
{
whereCause.Add("T1.status = @status");
}
string whereSql = $"WHERE (T1.`status` = {(short)ExamStatus.ACTIVE} OR T1.`status` = {(short)ExamStatus.STOPPED}) AND T1.is_deleted = 0 AND EDR.type = {(short)DataReportType.ABSENT_REPLACE}";
if (whereCause.Count > 0)
{
whereSql = $"{whereSql} AND {string.Join(" AND ", whereCause)}";
}
var p = new
{
input.PageSize,
PageOffset = (input.PageIndex - 1) * input.PageSize,
Type = DataReportType.ABSENT_REPLACE,
input.SemesterId,
input.Status,
input.Name,
};
var totalCount = await rep.SqlScalarAsync($@"
SELECT COUNT(1) AS total_count
FROM
(
SELECT T1.id, COUNT(T1.sys_org_id) AS org_count
FROM
(
SELECT T1.id, T2.sys_org_id
FROM exam_plan AS T1
JOIN exam_data_report AS EDR ON T1.id = EDR.exam_plan_id
LEFT JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
{whereSql}
GROUP BY T1.id, t2.sys_org_id
) AS T1
GROUP BY T1.id
) AS T
", p);
var items = await rep.SqlQueriesAsync($@"
SELECT
T1.id,
T1.full_name,
T1.short_name,
T1.`name`,
T1.semester_id,
T1.education_stage,
T1.`status`,
COUNT(DISTINCT T1.sys_org_id) AS org_count,
SUM(T1.total_count) AS total_count,
SUM(T1.audit_count) AS audit_count,
SUM(T1.approved_count) AS approved_count,
SUM(T1.rejected_count) AS rejected_count
FROM
(
SELECT
T1.id,
T1.full_name,
T1.short_name,
T1.`name`,
T1.semester_id,
T1.education_stage,
T1.`status`,
T2.sys_org_id,
COUNT(CASE WHEN T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED} THEN T4.id ELSE NULL END) AS total_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND (T4.`status` ={(short)AuditStatus.AUDIT} OR T4.`status` = {(short)AuditStatus.APPROVE_CANCELED}) THEN T4.id ELSE NULL END) AS audit_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.`status` = {(short)AuditStatus.APPROVED} THEN T4.id ELSE NULL END) AS approved_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.`status` = {(short)AuditStatus.REJECTED} THEN T4.id ELSE NULL END) AS rejected_count
FROM exam_plan AS T1
JOIN exam_data_report AS EDR ON T1.id = EDR.exam_plan_id
LEFT JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
LEFT JOIN (SELECT * FROM exam_org_data_report WHERE type = {(short)DataReportType.ABSENT_REPLACE}) AS T3 ON T2.id = T3.exam_org_id AND EDR.type = T3.type
LEFT JOIN exam_absent_replace AS T4 ON T1.id = T4.exam_plan_id AND T2.sys_org_id = T4.sys_org_id
{whereSql}
GROUP BY T1.id, T1.full_name, T1.short_name, T1.`name`, T1.semester_id, T1.education_stage, T1.`status`, T2.sys_org_id
) AS T1
GROUP BY T1.id, T1.full_name, T1.short_name, T1.`name`, T1.semester_id, T1.education_stage, T1.`status`
ORDER BY T1.id DESC
LIMIT @pageSize OFFSET @pageOffset;
", p);
PageResult ret = new()
{
PageIndex = input.PageIndex,
PageSize = input.PageSize,
TotalCount = totalCount,
Items = items
};
return ret;
}
///
/// 获取待审核机构列表
///
///
///
public async Task> QueryOrgAuditPageList(ExamOrgDataReportAuditPageInput input)
{
var roleDataScope = await sysRoleService.GetCurrentUserDataScope();
if (roleDataScope == null || roleDataScope.EducationStages.Count == 0)
{
return new();
}
var p = new
{
input.PageSize,
PageOffset = (input.PageIndex - 1) * input.PageSize,
input.ExamPlanId,
input.SearchValue,
input.SysOrgName,
input.ExamPlanName,
Type = (short)DataReportType.ABSENT_REPLACE,
};
List whereCause = new();
if (input.ExamPlanId.HasValue)
{
whereCause.Add("T1.id = @examPlanId");
}
if (roleDataScope.EducationStages.Count == 0)
{
whereCause.Add($"T1.education_stage = {(short)roleDataScope.EducationStages[0]}");
}
else
{
var ess = roleDataScope.EducationStages.Select(t => $"T1.education_stage = {(short)t}").ToList();
string wes = string.Join(" OR ", ess);
whereCause.Add($"({wes})");
}
if (input.SemesterId.HasValue)
{
whereCause.Add("T1.semester_id = @semesterId");
}
if (!string.IsNullOrEmpty(input.ExamPlanName?.Trim()))
{
whereCause.Add("T1.full_name LIKE '%@examPlanName%'");
}
if (!string.IsNullOrEmpty(input.SysOrgName?.Trim()))
{
whereCause.Add("ORG.full_name LIKE '%@sysOrgName%'");
}
string whereSql = $"WHERE (T1.`status` = {(short)ExamStatus.ACTIVE} OR T1.`status` = {(short)ExamStatus.STOPPED})";
if (whereCause.Count > 0)
{
whereSql = $"{whereSql} AND {string.Join(" AND ", whereCause)}";
}
string fromSql = $@"
FROM exam_plan AS T1
JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
JOIN sys_org AS ORG ON T2.sys_org_id = ORG.id
LEFT JOIN (SELECT * FROM exam_org_data_report WHERE type = {(short)DataReportType.ABSENT_REPLACE}) AS T3 ON T2.id = T3.exam_org_id
LEFT JOIN exam_absent_replace AS T4 ON T1.id = T4.exam_plan_id AND T2.sys_org_id = T4.sys_org_id
";
string groupSql = @"GROUP BY T2.exam_plan_id, T1.full_name, T1.`name`, T1.semester_id, T1.education_stage, T1.`status`, T2.sys_org_id, ORG.full_name, ORG.`name`, ORG.`code`, T3.`status`, T3.report_time";
var totalCount = await rep.SqlScalarAsync($@"
SELECT COUNT(1) AS total_count
FROM
(
SELECT COUNT(1) AS total_count
{fromSql}
{whereSql}
{groupSql}
) AS T", p);
var items = await rep.SqlQueriesAsync($@"
SELECT ROW_NUMBER() OVER (ORDER BY T.exam_plan_id DESC, T.audit_count DESC, T.report_time) AS `row_number`, T.*
FROM
(
SELECT
T2.exam_plan_id,
T1.full_name AS exam_plan_full_name,
T1.`name` AS exam_plan_name,
T1.semester_id,
T1.education_stage,
T1.`status` AS exam_status,
T2.sys_org_id,
ORG.full_name AS sys_org_full_name,
ORG.`name` AS sys_org_name,
ORG.`code` AS sys_org_code,
IFNULL(T3.`status`, 1) AS data_report_status,
T3.report_time,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) THEN T4.id ELSE NULL END) AS total_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND (T4.`status` = {(short)AuditStatus.AUDIT} OR T4.`status` = {(short)AuditStatus.APPROVE_CANCELED}) THEN T4.id ELSE NULL END) AS audit_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.`status` = {(short)AuditStatus.APPROVED} THEN T4.id ELSE NULL END) AS approved_count,
COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.`status` = {(short)AuditStatus.REJECTED} THEN T4.id ELSE NULL END) AS rejected_count
{fromSql}
{whereSql}
{groupSql}
) AS T
ORDER BY T.exam_plan_id DESC, T.audit_count DESC, T.data_report_status DESC, T.report_time DESC
LIMIT @pageSize OFFSET @pageOffset;
", p);
PageResult ret = new()
{
PageIndex = input.PageIndex,
PageSize = input.PageSize,
TotalCount = totalCount,
Items = items
};
return ret;
}
}