ExamAbsentReplaceAuditService.cs 12 KB

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