ExamSpecialStudentAuditService.cs 12 KB

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