ExamAbsentReplaceCenterService.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. using Furion.JsonSerialization;
  2. using NPOI.SS.UserModel;
  3. using NPOI.XSSF.UserModel;
  4. using System.Data;
  5. using YBEE.EQM.Core;
  6. namespace YBEE.EQM.Application;
  7. /// <summary>
  8. /// 缺测替补管理服务(用于中心管理)
  9. /// </summary>
  10. public class ExamAbsentReplaceCenterService(
  11. IRepository<ExamAbsentReplace> rep,
  12. IExportExcelService exportExcelService,
  13. ICourseService courseService,
  14. IExamPlanService examPlanService
  15. ) : IExamAbsentReplaceCenterService, ITransient
  16. {
  17. /// <summary>
  18. /// 分页查询监测缺测替补列表
  19. /// </summary>
  20. /// <param name="input"></param>
  21. /// <returns></returns>
  22. public async Task<PageResult<ExamAbsentReplaceFullOutput>> QueryPageList(ExamAbsentReplacePageInput input)
  23. {
  24. var query = GetQueryBase(input);
  25. var ret = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id)
  26. .ProjectToType<ExamAbsentReplaceFullOutput>()
  27. .ToADPagedListAsync(input.PageIndex, input.PageSize);
  28. return ret;
  29. }
  30. /// <summary>
  31. /// 获取状态数量
  32. /// </summary>
  33. /// <returns></returns>
  34. public async Task<List<StatusCount>> QueryStatusCount(ExamAbsentReplacePageInput input)
  35. {
  36. var query = GetQueryBase(input);
  37. if (query == null)
  38. {
  39. return [];
  40. }
  41. var counts = await query.GroupBy(t => t.Status).Select(t => new StatusCount { Status = (int)t.Key, Count = t.Count() }).ToListAsync();
  42. return counts;
  43. }
  44. /// <summary>
  45. /// 导出数据表格(简表)
  46. /// </summary>
  47. /// <param name="input"></param>
  48. /// <returns></returns>
  49. public async Task<(string fileName, byte[] fileBytes)> ExportSimple(ExamAbsentReplacePageInput input)
  50. {
  51. var examPlan = await examPlanService.GetById(input.ExamPlanId);
  52. var query = GetQueryBase(input);
  53. var items = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id)
  54. .ProjectToType<ExamAbsentReplaceFullOutput>()
  55. .ToListAsync();
  56. // 科目列表
  57. var courses = await courseService.GetAllLiteList();
  58. // 科目字典
  59. var courseDicts = courses.ToDictionary(t => t.Name);
  60. XSSFWorkbook wb = new();
  61. ISheet sheet = wb.CreateSheet("缺测替补名单");
  62. sheet.DisplayGridlines = false;
  63. var cellStyle = exportExcelService.GetCellStyle(wb);
  64. // 行索引号
  65. int rowNum = 0;
  66. #region 列头
  67. IRow headerRow = sheet.CreateRow(rowNum++);
  68. int ci = 0;
  69. exportExcelService.AddCell("学校", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 20);
  70. exportExcelService.AddCell("年级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  71. exportExcelService.AddCell("班级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  72. exportExcelService.AddCell("缺测姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12);
  73. exportExcelService.AddCell("缺测考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16);
  74. exportExcelService.AddCell("有无替补", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 10);
  75. exportExcelService.AddCell("替补姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12);
  76. exportExcelService.AddCell("替补考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16);
  77. exportExcelService.AddCell("缺测替补科目", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 50);
  78. exportExcelService.AddCell("状态", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  79. sheet.CreateFreezePane(0, rowNum);
  80. #endregion
  81. #region 数据
  82. foreach (var item in items)
  83. {
  84. IRow row = sheet.CreateRow(rowNum++);
  85. int rci = 0;
  86. exportExcelService.AddCell(item.SysOrg.Name, row, rci++, cellStyle.LeftCellStyle);
  87. exportExcelService.AddCell(item.ExamGrade.Grade.Name, row, rci++, cellStyle.CenterCellStyle);
  88. exportExcelService.AddCell(item.ClassNumber, row, rci++, cellStyle.CenterCellStyle);
  89. exportExcelService.AddCell(item.AbsentName, row, rci++, cellStyle.CenterCellStyle);
  90. exportExcelService.AddCell(item.AbsentExamNumber, row, rci++, cellStyle.CenterCellStyle);
  91. exportExcelService.AddCell(item.IsReplaced ? "是" : "否", row, rci++, cellStyle.CenterCellStyle);
  92. exportExcelService.AddCell(item.ReplaceName, row, rci++, cellStyle.CenterCellStyle);
  93. exportExcelService.AddCell(item.ReplaceExamNumber, row, rci++, cellStyle.CenterCellStyle);
  94. var cs = JSON.Deserialize<List<CourseMiniOutput>>(item.AbsentCourses);
  95. var cns = string.Join("、", cs.Select(t => t.Name));
  96. exportExcelService.AddCell(cns, row, rci++, cellStyle.LeftCellStyle);
  97. exportExcelService.AddCell(item.Status.GetDescription(), row, rci++, cellStyle.CenterCellStyle);
  98. }
  99. #endregion
  100. MemoryStream ms = new();
  101. wb.Write(ms, false);
  102. ms.Flush();
  103. return ($"{examPlan.Name}-缺测替补名单.xlsx", ms.ToArray());
  104. }
  105. /// <summary>
  106. /// 导出数据表格(完整)
  107. /// </summary>
  108. /// <param name="input"></param>
  109. /// <returns></returns>
  110. public async Task<(string fileName, byte[] fileBytes)> ExportFull(ExamAbsentReplacePageInput input)
  111. {
  112. var examPlan = await examPlanService.GetById(input.ExamPlanId);
  113. var query = GetQueryBase(input);
  114. var items = await query.OrderBy(t => t.SysOrgId).ThenBy(t => t.GradeId).ThenBy(t => t.ClassNumber).ThenBy(t => t.Id)
  115. .ProjectToType<ExamAbsentReplaceFullOutput>()
  116. .ToListAsync();
  117. // 科目列表
  118. var courses = await courseService.GetAllLiteList();
  119. // 科目字典
  120. var courseDicts = courses.ToDictionary(t => t.Name);
  121. XSSFWorkbook wb = new();
  122. ISheet sheet = wb.CreateSheet("缺测替补名单");
  123. sheet.DisplayGridlines = false;
  124. var cellStyle = exportExcelService.GetCellStyle(wb);
  125. // 行索引号
  126. int rowNum = 0;
  127. #region 列头
  128. IRow headerRow = sheet.CreateRow(rowNum++);
  129. int ci = 0;
  130. exportExcelService.AddCell("学校", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 20);
  131. exportExcelService.AddCell("年级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  132. exportExcelService.AddCell("班级", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  133. exportExcelService.AddCell("缺测姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12);
  134. exportExcelService.AddCell("缺测考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16);
  135. exportExcelService.AddCell("有无替补", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 10);
  136. exportExcelService.AddCell("替补姓名", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12);
  137. exportExcelService.AddCell("替补考号", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 16);
  138. exportExcelService.AddCell("缺测替补科目", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 50);
  139. exportExcelService.AddCell("状态", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 8);
  140. exportExcelService.AddCell("缺测原因", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 40);
  141. exportExcelService.AddCell("家长电话", headerRow, ci++, cellStyle.ColumnFillHeaderStyle, sheet, 12);
  142. sheet.CreateFreezePane(0, rowNum);
  143. #endregion
  144. #region 数据
  145. foreach (var item in items)
  146. {
  147. IRow row = sheet.CreateRow(rowNum++);
  148. int rci = 0;
  149. exportExcelService.AddCell(item.SysOrg.Name, row, rci++, cellStyle.LeftCellStyle);
  150. exportExcelService.AddCell(item.ExamGrade.Grade.Name, row, rci++, cellStyle.CenterCellStyle);
  151. exportExcelService.AddCell(item.ClassNumber, row, rci++, cellStyle.CenterCellStyle);
  152. exportExcelService.AddCell(item.AbsentName, row, rci++, cellStyle.CenterCellStyle);
  153. exportExcelService.AddCell(item.AbsentExamNumber, row, rci++, cellStyle.CenterCellStyle);
  154. exportExcelService.AddCell(item.IsReplaced ? "是" : "否", row, rci++, cellStyle.CenterCellStyle);
  155. exportExcelService.AddCell(item.ReplaceName, row, rci++, cellStyle.CenterCellStyle);
  156. exportExcelService.AddCell(item.ReplaceExamNumber, row, rci++, cellStyle.CenterCellStyle);
  157. var cs = JSON.Deserialize<List<CourseMiniOutput>>(item.AbsentCourses);
  158. var cns = string.Join("、", cs.Select(t => t.Name));
  159. exportExcelService.AddCell(cns, row, rci++, cellStyle.LeftCellStyle);
  160. exportExcelService.AddCell(item.Status.GetDescription(), row, rci++, cellStyle.CenterCellStyle);
  161. exportExcelService.AddCell(item.AbsentReason, row, rci++, cellStyle.LeftWrapCellStyle);
  162. exportExcelService.AddCell(item.PatriarchTel, row, rci++, cellStyle.CenterCellStyle);
  163. }
  164. #endregion
  165. MemoryStream ms = new();
  166. wb.Write(ms, false);
  167. ms.Flush();
  168. return ($"{examPlan.Name}-缺测替补名单.xlsx", ms.ToArray());
  169. }
  170. #region 私有方法
  171. /// <summary>
  172. /// 构建查询
  173. /// </summary>
  174. /// <param name="input"></param>
  175. /// <returns></returns>
  176. private IQueryable<ExamAbsentReplace> GetQueryBase(ExamAbsentReplacePageInput input)
  177. {
  178. var absentName = !string.IsNullOrEmpty(input.AbsentName?.Trim());
  179. var absentExamNumber = !string.IsNullOrEmpty(input.AbsentExamNumber?.Trim());
  180. var absentReason = !string.IsNullOrEmpty(input.AbsentReason?.Trim());
  181. var replaceName = !string.IsNullOrEmpty(input.ReplaceName?.Trim());
  182. var replaceExamNumber = !string.IsNullOrEmpty(input.ReplaceExamNumber?.Trim());
  183. var patriarchTel = !string.IsNullOrEmpty(input.PatriarchTel?.Trim());
  184. var remark = !string.IsNullOrEmpty(input.Remark?.Trim());
  185. var query = rep.DetachedEntities.Where(t => t.ExamPlanId == input.ExamPlanId)
  186. .Where((absentName, u => EF.Functions.Like(u.AbsentName, $"%{input.AbsentName.Trim()}%")))
  187. .Where((absentExamNumber, u => EF.Functions.Like(u.AbsentExamNumber, $"%{input.AbsentExamNumber.Trim()}%")))
  188. .Where((absentReason, u => EF.Functions.Like(u.AbsentReason, $"%{input.AbsentReason.Trim()}%")))
  189. .Where((replaceName, u => EF.Functions.Like(u.ReplaceName, $"%{input.ReplaceName.Trim()}%")))
  190. .Where((replaceExamNumber, u => EF.Functions.Like(u.ReplaceExamNumber, $"%{input.ReplaceExamNumber.Trim()}%")))
  191. .Where((patriarchTel, u => EF.Functions.Like(u.PatriarchTel, $"%{input.PatriarchTel.Trim()}%")))
  192. .Where((remark, u => EF.Functions.Like(u.Remark, $"%{input.Remark.Trim()}%")))
  193. .Where((input.AbentCourseId.HasValue, u => EF.Functions.Like(u.AbsentCourses, $"%{input.AbentCourseId}%")))
  194. .Where(input.Status.HasValue, t => t.Status == input.Status)
  195. .Where(input.IsReplaced.HasValue, t => t.IsReplaced == input.IsReplaced)
  196. .Where(input.GradeId.HasValue, t => t.GradeId == input.GradeId)
  197. .Where(input.ClassNumber.HasValue, t => t.ClassNumber == input.ClassNumber)
  198. .Where(input.SysOrgId.HasValue, t => t.SysOrgId == input.SysOrgId)
  199. .Where(input.SysOrgBranchId.HasValue, t => t.SchoolClass.SysOrgBranchId == input.SysOrgBranchId);
  200. return query;
  201. }
  202. #endregion
  203. }