using Furion.DatabaseAccessor.Extensions; using Furion.JsonSerialization; using YBEE.EQM.Core; namespace YBEE.EQM.Application; /// /// 监测机构上报类型服务 /// public class ExamOrgDataReportService : IExamOrgDataReportService, ITransient { private readonly IRepository _rep; private readonly IResourceFileService _resourceFileService; private readonly IExamSpecialStudentService _examSpecialStudentService; private readonly IExamAbsentReplaceService _examAbsentReplaceService; public ExamOrgDataReportService(IRepository rep, IResourceFileService resourceFileService, IExamSpecialStudentService examSpecialStudentService, IExamAbsentReplaceService examAbsentReplaceService) { _rep = rep; _resourceFileService = resourceFileService; _examSpecialStudentService = examSpecialStudentService; _examAbsentReplaceService = examAbsentReplaceService; } /// /// 提交上报 /// /// /// public async Task Submit(SubmitExamOrgDataReportInput input) { var orgId = CurrentSysUserInfo.SysOrgId; var examOrg = await _rep.Change().DetachedEntities .Include(t => t.ExamPlan).ThenInclude(t => t.ExamDataReports) .FirstOrDefaultAsync(t => t.SysOrgId == orgId && t.ExamPlanId == input.ExamPlanId); var edr = examOrg.ExamPlan.ExamDataReports.FirstOrDefault(t => t.Type == input.Type) ?? throw Oops.Oh(ErrorCode.E2001); if (edr.Status != ExamStatus.ACTIVE) { throw Oops.Oh(ErrorCode.E2006); } if (edr.EndTime < DateTime.Now) { throw Oops.Oh(ErrorCode.E2008); } if (input.Type == DataReportType.SP_STUDENT) { var vspSuccess = await _examSpecialStudentService.VerifyAttachment(input.ExamPlanId); if (vspSuccess == false) { throw Oops.Oh(ErrorCode.E1012, "特殊学生明细"); } } else if(input.Type == DataReportType.ABSENT_REPLACE) { var vspSuccess = await _examAbsentReplaceService.VerifyAttachment(input.ExamPlanId); if (vspSuccess == false) { throw Oops.Oh(ErrorCode.E1012, "缺测替补学生明细"); } } var item = await _rep.FirstOrDefaultAsync(t => t.ExamOrg.SysOrgId == CurrentSysUserInfo.SysOrgId && t.ExamOrg.ExamPlanId == input.ExamPlanId && t.Type == input.Type); if (item == null) { item = new ExamOrgDataReport() { Type = input.Type, Status = DataReportStatus.REPORTED, ReportSysUserId = CurrentSysUserInfo.SysUserId, ReportTime = DateTime.Now, ExamOrgId = examOrg.Id, ExamPlanId = input.ExamPlanId, SysOrgId = orgId, }; await _rep.InsertNowAsync(item); } else { item.Status = DataReportStatus.REPORTED; item.ReportSysUserId = CurrentSysUserInfo.SysUserId; item.ReportTime = DateTime.Now; await item.UpdateIncludeNowAsync(new[] { nameof(item.Status), nameof(item.ReportSysUserId), nameof(item.ReportTime) }); } } /// /// 添加特殊学生佐证材料 /// /// /// public async Task AddAttachment(AddExamOrgDataReportAttachmentInput input) { var orgId = CurrentSysUserInfo.SysOrgId; var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.SourceId); bool hasItem = true; if (item == null) { hasItem = false; var examOrg = await _rep.Change().DetachedEntities.FirstOrDefaultAsync(t => t.SysOrgId == orgId && t.ExamPlanId == input.ExamPlanId) ?? throw Oops.Oh(ErrorCode.E2001, "监测机构"); item = new() { Type = input.Type, Status = DataReportStatus.UNREPORT, ExamOrgId = examOrg.Id, ExamPlanId = input.ExamPlanId, SysOrgId = orgId, }; } item.Attachments = AttachmentUtil.InsertInto(item.Attachments, input.Adapt()); if (hasItem) { await item.UpdateIncludeAsync(new[] { nameof(item.Attachments) }); } else { await _rep.InsertNowAsync(item); } } /// /// 删除特殊学生佐证材料 /// /// /// public async Task DelAttachment(DeleteAttachmentInput input) { var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.SourceId) ?? throw Oops.Oh(ErrorCode.E2001); var attachments = AttachmentUtil.GetList(item.Attachments); var a = attachments.FirstOrDefault(t => t.FileId == input.FileId); if (a != null) { attachments.Remove(a); item.Attachments = JSON.Serialize(attachments); await item.UpdateIncludeAsync(new[] { nameof(item.Attachments) }); await _resourceFileService.Del(new() { Id = a.FileId }); if (a.ThumbFileId.HasValue && a.ThumbFileId > 0) { await _resourceFileService.Del(new() { Id = a.ThumbFileId.Value }); } } } /// /// 退回机构上报 /// /// /// public async Task ReportReject(BaseId input) { var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.Id); item.Status = DataReportStatus.REJECTED; await item.UpdateIncludeAsync(new[] { nameof(item.Status) }); } /// /// 获取监测机构上报类型列表 /// /// /// 不传取当前机构ID /// public async Task> GetListByExamPlanId(int examPlanId, short? sysOrgId = null) { var orgId = sysOrgId ?? CurrentSysUserInfo.SysOrgId; var pitems = await _rep.Change().DetachedEntities.Where(t => t.ExamPlanId == examPlanId).ToListAsync(); var oitems = await _rep.DetachedEntities.Include(t => t.ExamOrg).ThenInclude(t => t.SysOrg) .Include(t => t.ReportSysUser) .Where(t => t.ExamOrg.SysOrgId == orgId && t.ExamOrg.ExamPlanId == examPlanId) .ToListAsync(); var items = from p in pitems join o in oitems on p.Type equals o.Type into temp from u in temp.DefaultIfEmpty() select new ExamOrgDataReportUnionOutput { ExamDataReportId = p.Id, ExamDataReport = p.Adapt(), ExamOrgDataReportId = u?.Id ?? 0, ExamOrgDataReport = u == null ? new() : u.Adapt(), SysOrgId = orgId, IsExpired = p.EndTime < DateTime.Now, }; return items.ToList(); } /// /// 根据监测计划ID和上报类型获取机构上报信息 /// /// /// /// /// public async Task GetByTypeExamPlanId(DataReportType type, int examPlanId, short? sysOrgId = null) { var items = await GetListByExamPlanId(examPlanId, sysOrgId); var item = items.FirstOrDefault(t => t.ExamDataReport.Type == type) ?? throw Oops.Oh(ErrorCode.E2001); item.ExamPlan = (await _rep.Change().DetachedEntities.FirstOrDefaultAsync(t => t.Id == examPlanId))?.Adapt(); return item; } /// /// 分页查询机构上报类型列表 /// /// /// public async Task> QueryPageList(ExamOrgDataReportPageInput input) { string where = "T2.type = @type AND T1.sys_org_id = @sysOrgId AND (T4.status = 2 OR T4.status = 3) AND T4.is_deleted = 0"; if (input.Status.HasValue) { where = $"{where} AND T3.status = {(short)input.Status.Value}"; } if (input.SemesterId.HasValue) { where = $"{where} AND T4.semester_id = {(short)input.SemesterId.Value}"; } if (!string.IsNullOrEmpty(input.Name?.Trim())) { where = $"{where} AND T4.full_name LIKE '%{input.Name.Trim()}%'"; } var p = new { CurrentSysUserInfo.SysOrgId, input.PageSize, PageOffset = (input.PageIndex - 1) * input.PageSize, input.Type, input.Status, input.Name, input.SemesterId, }; var totalCount = await _rep.SqlScalarAsync($@" SELECT COUNT(1) AS total_count FROM exam_org AS T1 JOIN exam_data_report AS T2 ON T1.exam_plan_id = T2.exam_plan_id INNER JOIN exam_plan AS T4 ON T1.exam_plan_id = T4.id LEFT JOIN exam_org_data_report AS T3 ON T1.id = T3.exam_org_id AND T2.type = T3.type WHERE {where}", p); var items = await _rep.SqlQueriesAsync($@" SELECT ROW_NUMBER() OVER (ORDER BY T1.exam_plan_id DESC, T2.type) AS `row_number`, T1.exam_plan_id, T1.sys_org_id, T2.type, T2.begin_time, T2.end_time, T2.`status` AS exam_status, IFNULL(T3.`status`, 1) AS `status`, T3.report_sys_user_id, T5.`name` AS report_sys_user_name, T3.report_time, T4.full_name AS exam_plan_full_name, T4.`name` AS exam_plan_name, T4.short_name AS exam_plan_short_name, T4.`status` AS exam_plan_status, T4.education_stage, T4.semester_id FROM exam_org AS T1 JOIN exam_data_report AS T2 ON T1.exam_plan_id = T2.exam_plan_id JOIN exam_plan AS T4 ON T1.exam_plan_id = T4.id LEFT JOIN exam_org_data_report AS T3 ON T1.id = T3.exam_org_id AND T2.type = T3.type LEFT JOIN sys_user AS T5 ON T3.report_sys_user_id = T5.id WHERE {where} LIMIT @pageSize OFFSET @pageOffset;", p); PageResult ret = new() { PageIndex = input.PageIndex, PageSize = input.PageSize, TotalCount = totalCount, Items = items }; return ret; } public async Task RefreshFileSize() { var items = await _rep.Entities.ToListAsync(); foreach (var item in items) { var ats = AttachmentUtil.GetList(item.Attachments); foreach (var at in ats) { var file = await _rep.Change().DetachedEntities.FirstOrDefaultAsync(t => t.Id == at.FileId) ?? throw new Exception("fuckfuck"); at.FileSize = file.FileSize; } item.Attachments = JSON.Serialize(ats); } await _rep.UpdateAsync(items); } }