ExamSpecialStudentAuditService.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. using Furion.DatabaseAccessor.Extensions;
  2. using YBEE.EQM.Core;
  3. namespace YBEE.EQM.Application;
  4. /// <summary>
  5. /// 特殊学生审核服务
  6. /// </summary>
  7. public class ExamSpecialStudentAuditService : IExamSpecialStudentAuditService, ITransient
  8. {
  9. private readonly IRepository<ExamSpecialStudent> _rep;
  10. private readonly ISysRoleService _sysRoleService;
  11. public ExamSpecialStudentAuditService(IRepository<ExamSpecialStudent> rep, ISysRoleService sysRoleService)
  12. {
  13. _rep = rep;
  14. _sysRoleService = sysRoleService;
  15. }
  16. /// <summary>
  17. /// 提交审核
  18. /// </summary>
  19. /// <param name="input"></param>
  20. /// <returns></returns>
  21. public async Task Submit(BaseId input)
  22. {
  23. var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  24. if (item.Status != AuditStatus.UNSUBMIT || item.Status != AuditStatus.REJECTED)
  25. {
  26. throw Oops.Oh(ErrorCode.E2006);
  27. }
  28. item.Status = AuditStatus.AUDIT;
  29. item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(AuditActionType.SUBMIT, item.Status));
  30. await item.UpdateAsync();
  31. }
  32. /// <summary>
  33. /// 审核
  34. /// </summary>
  35. /// <param name="input"></param>
  36. /// <returns></returns>
  37. public async Task Audit(ExamSepcialStudentAuditInput input)
  38. {
  39. var dt = DateTime.Now;
  40. var items = await _rep.Where(t => input.Ids.Contains(t.Id)).ToListAsync();
  41. foreach (var item in items)
  42. {
  43. item.Status = input.IsApproved ? AuditStatus.APPROVED : AuditStatus.REJECTED;
  44. item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(input.IsApproved ? AuditActionType.APPROVE : AuditActionType.REJECT, item.Status, dt, input.Remark));
  45. }
  46. await _rep.UpdateAsync(items);
  47. }
  48. /// <summary>
  49. /// 反审
  50. /// </summary>
  51. /// <param name="input"></param>
  52. /// <returns></returns>
  53. public async Task Reaudit(BaseId input)
  54. {
  55. var item = await _rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  56. if (item.Status != AuditStatus.APPROVED)
  57. {
  58. throw Oops.Oh(ErrorCode.E2006);
  59. }
  60. item.Status = AuditStatus.APPROVE_CANCELED;
  61. item.Audits = AuditUtil.InsertInto(item.Audits, AuditUtil.CreateNew(AuditActionType.REAUDIT, item.Status));
  62. await item.UpdateAsync();
  63. }
  64. //public async Task<byte[]> ExportAll(int examPlanId)
  65. //{
  66. //}
  67. /// <summary>
  68. /// 获取待审核监测计划列表
  69. /// </summary>
  70. /// <param name="input"></param>
  71. /// <returns></returns>
  72. public async Task<PageResult<ExamPlanAuditOutput>> QueryExamPlanPageList(ExamPlanPageInput input)
  73. {
  74. var roleDataScope = await _sysRoleService.GetCurrentUserDataScope();
  75. if (roleDataScope == null || roleDataScope.EducationStages.Count == 0)
  76. {
  77. return new();
  78. }
  79. List<string> whereCause = new();
  80. if (roleDataScope.EducationStages.Count == 0)
  81. {
  82. whereCause.Add($"T1.education_stage = {(short)roleDataScope.EducationStages[0]}");
  83. }
  84. else
  85. {
  86. var ess = roleDataScope.EducationStages.Select(t => $"T1.education_stage = {(short)t}").ToList();
  87. string wes = string.Join(" OR ", ess);
  88. whereCause.Add($"({wes})");
  89. }
  90. if (!string.IsNullOrEmpty(input.Name?.Trim()))
  91. {
  92. whereCause.Add("T1.full_name LIKE '%@name%'");
  93. }
  94. if (input.SemesterId.HasValue)
  95. {
  96. whereCause.Add("T1.semester_id = @semesterId");
  97. }
  98. if (input.Status.HasValue)
  99. {
  100. whereCause.Add("T1.status = @status");
  101. }
  102. string whereSql = $"WHERE (T1.`status` = {(short)ExamStatus.ACTIVE} OR T1.`status` = {(short)ExamStatus.STOPPED}) AND EDR.type = {(short)DataReportType.SP_STUDENT}";
  103. if (whereCause.Count > 0)
  104. {
  105. whereSql = $"{whereSql} AND {string.Join(" AND ", whereCause)}";
  106. }
  107. var p = new
  108. {
  109. input.PageSize,
  110. PageOffset = (input.PageIndex - 1) * input.PageSize,
  111. Type = DataReportType.SP_STUDENT,
  112. input.SemesterId,
  113. input.Status,
  114. input.Name,
  115. };
  116. var totalCount = await _rep.SqlScalarAsync<int>($@"
  117. SELECT COUNT(1) AS total_count
  118. FROM
  119. (
  120. SELECT T1.id, COUNT(T1.sys_org_id) AS org_count
  121. FROM
  122. (
  123. SELECT T1.id, T2.sys_org_id
  124. FROM exam_plan AS T1
  125. JOIN exam_data_report AS EDR ON T1.id = EDR.exam_plan_id
  126. LEFT JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
  127. {whereSql}
  128. GROUP BY T1.id, t2.sys_org_id
  129. ) AS T1
  130. GROUP BY T1.id
  131. ) AS T
  132. ", p);
  133. var items = await _rep.SqlQueriesAsync<ExamPlanAuditOutput>($@"
  134. SELECT
  135. T1.id,
  136. T1.full_name,
  137. T1.short_name,
  138. T1.`name`,
  139. T1.semester_id,
  140. T1.education_stage,
  141. T1.`status`,
  142. COUNT(DISTINCT T1.sys_org_id) AS org_count,
  143. SUM(T1.total_count) AS total_count,
  144. SUM(T1.audit_count) AS audit_count,
  145. SUM(T1.approved_count) AS approved_count,
  146. SUM(T1.rejected_count) AS rejected_count,
  147. SUM(T1.pre_identified_count) AS pre_identified_count
  148. FROM
  149. (
  150. SELECT
  151. T1.id,
  152. T1.full_name,
  153. T1.short_name,
  154. T1.`name`,
  155. T1.semester_id,
  156. T1.education_stage,
  157. T1.`status`,
  158. T2.sys_org_id,
  159. COUNT(CASE WHEN T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED} THEN T4.id ELSE NULL END) AS total_count,
  160. 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,
  161. 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,
  162. 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,
  163. COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.is_pre_identified = 1 THEN T4.id ELSE NULL END) AS pre_identified_count
  164. FROM exam_plan AS T1
  165. JOIN exam_data_report AS EDR ON T1.id = EDR.exam_plan_id
  166. LEFT JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
  167. LEFT JOIN (SELECT * FROM exam_org_data_report WHERE type = 2) AS T3 ON T2.id = T3.exam_org_id AND EDR.type = T3.type
  168. LEFT JOIN exam_special_student AS T4 ON T1.id = T4.exam_plan_id AND T2.sys_org_id = T4.sys_org_id
  169. {whereSql}
  170. GROUP BY T1.id, T1.full_name, T1.short_name, T1.`name`, T1.semester_id, T1.education_stage, T1.`status`, T2.sys_org_id
  171. ) AS T1
  172. GROUP BY T1.id, T1.full_name, T1.short_name, T1.`name`, T1.semester_id, T1.education_stage, T1.`status`
  173. ORDER BY T1.id DESC
  174. LIMIT @pageSize OFFSET @pageOffset;
  175. ", p);
  176. PageResult<ExamPlanAuditOutput> ret = new()
  177. {
  178. PageIndex = input.PageIndex,
  179. PageSize = input.PageSize,
  180. TotalCount = totalCount,
  181. Items = items
  182. };
  183. return ret;
  184. }
  185. /// <summary>
  186. /// 获取待审核机构列表
  187. /// </summary>
  188. /// <param name="input"></param>
  189. /// <returns></returns>
  190. public async Task<PageResult<ExamPlanOrgAuditOutput>> QueryOrgAuditPageList(ExamOrgDataReportAuditPageInput input)
  191. {
  192. var roleDataScope = await _sysRoleService.GetCurrentUserDataScope();
  193. if (roleDataScope == null || roleDataScope.EducationStages.Count == 0)
  194. {
  195. return new();
  196. }
  197. var p = new
  198. {
  199. input.PageSize,
  200. PageOffset = (input.PageIndex - 1) * input.PageSize,
  201. input.ExamPlanId,
  202. input.SearchValue,
  203. input.SysOrgName,
  204. input.ExamPlanName,
  205. Type = (short)DataReportType.SP_STUDENT,
  206. };
  207. List<string> whereCause = new();
  208. if (input.ExamPlanId.HasValue)
  209. {
  210. whereCause.Add("T1.id = @examPlanId");
  211. }
  212. if (roleDataScope.EducationStages.Count == 0)
  213. {
  214. whereCause.Add($"T1.education_stage = {(short)roleDataScope.EducationStages[0]}");
  215. }
  216. else
  217. {
  218. var ess = roleDataScope.EducationStages.Select(t => $"T1.education_stage = {(short)t}").ToList();
  219. string wes = string.Join(" OR ", ess);
  220. whereCause.Add($"({wes})");
  221. }
  222. if (input.SemesterId.HasValue)
  223. {
  224. whereCause.Add("T1.semester_id = @semesterId");
  225. }
  226. if (!string.IsNullOrEmpty(input.ExamPlanName?.Trim()))
  227. {
  228. whereCause.Add("T1.full_name LIKE '%@examPlanName%'");
  229. }
  230. if (!string.IsNullOrEmpty(input.SysOrgName?.Trim()))
  231. {
  232. whereCause.Add("ORG.full_name LIKE '%@sysOrgName%'");
  233. }
  234. string whereSql = $"WHERE (T1.`status` = {(short)ExamStatus.ACTIVE} OR T1.`status` = {(short)ExamStatus.STOPPED})";
  235. if (whereCause.Count > 0)
  236. {
  237. whereSql = $"{whereSql} AND {string.Join(" AND ", whereCause)}";
  238. }
  239. string fromSql = $@"
  240. FROM exam_plan AS T1
  241. JOIN exam_org AS T2 ON T1.id = T2.exam_plan_id
  242. JOIN sys_org AS ORG ON T2.sys_org_id = ORG.id
  243. LEFT JOIN (SELECT * FROM exam_org_data_report WHERE type = {(short)DataReportType.SP_STUDENT}) AS T3 ON T2.id = T3.exam_org_id
  244. LEFT JOIN exam_special_student AS T4 ON T1.id = T4.exam_plan_id AND T2.sys_org_id = T4.sys_org_id
  245. ";
  246. 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";
  247. var totalCount = await _rep.SqlScalarAsync<int>($@"
  248. SELECT COUNT(1) AS total_count
  249. FROM
  250. (
  251. SELECT COUNT(1) AS total_count
  252. {fromSql}
  253. {whereSql}
  254. {groupSql}
  255. ) AS T", p);
  256. var items = await _rep.SqlQueriesAsync<ExamPlanOrgAuditOutput>($@"
  257. SELECT ROW_NUMBER() OVER (ORDER BY T.exam_plan_id DESC, T.audit_count DESC, T.report_time) AS `row_number`, T.*
  258. FROM
  259. (
  260. SELECT
  261. T2.exam_plan_id,
  262. T1.full_name AS exam_plan_full_name,
  263. T1.`name` AS exam_plan_name,
  264. T1.semester_id,
  265. T1.education_stage,
  266. T1.`status` AS exam_status,
  267. T2.sys_org_id,
  268. ORG.full_name AS sys_org_full_name,
  269. ORG.`name` AS sys_org_name,
  270. ORG.`code` AS sys_org_code,
  271. IFNULL(T3.`status`, 1) AS data_report_status,
  272. T3.report_time,
  273. COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) THEN T4.id ELSE NULL END) AS total_count,
  274. 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,
  275. 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,
  276. 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,
  277. COUNT(CASE WHEN (T3.`status` = {(short)DataReportStatus.REPORTED} OR T3.`status` = {(short)DataReportStatus.REJECTED}) AND T4.is_pre_identified = 1 THEN T4.id ELSE NULL END) AS pre_identified_count
  278. {fromSql}
  279. {whereSql}
  280. {groupSql}
  281. ) AS T
  282. ORDER BY T.exam_plan_id DESC, T.audit_count DESC, T.data_report_status DESC, T.report_time DESC
  283. LIMIT @pageSize OFFSET @pageOffset;
  284. ", p);
  285. PageResult<ExamPlanOrgAuditOutput> ret = new()
  286. {
  287. PageIndex = input.PageIndex,
  288. PageSize = input.PageSize,
  289. TotalCount = totalCount,
  290. Items = items
  291. };
  292. return ret;
  293. }
  294. }