ExamPlanService.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using Furion.DatabaseAccessor.Extensions;
  2. using YBEE.EQM.Core;
  3. namespace YBEE.EQM.Application;
  4. /// <summary>
  5. /// 监测计划管理服务
  6. /// </summary>
  7. public class ExamPlanService(IRepository<ExamPlan> rep, IEducationStageYearsService educationStageYearsService) : IExamPlanService, ITransient
  8. {
  9. #region 创建更新
  10. /// <summary>
  11. /// 添加监测计划
  12. /// </summary>
  13. /// <param name="input"></param>
  14. /// <returns></returns>
  15. public async Task Add(AddExamPlanInput input)
  16. {
  17. var ey = await educationStageYearsService.GetByEducationStage(input.EducationStage);
  18. //var maxExam = await _rep.Where(t => t.EducationStage == input.EducationStage && t.ExamPeriodType == input.ExamPeriodType && t.ExamType == input.ExamType && t.SemesterId == input.SemesterId).OrderByDescending(t => t.Sequence).FirstOrDefaultAsync();
  19. var maxExam = await rep.Where(t => t.EducationStage == input.EducationStage && t.SemesterId == input.SemesterId).OrderByDescending(t => t.Sequence).FirstOrDefaultAsync();
  20. short seq = maxExam?.Sequence ?? 0;
  21. var item = input.Adapt<ExamPlan>();
  22. item.Sequence = (short)(seq + 1);
  23. item.EducationYears = ey.EducationYears;
  24. await item.InsertAsync();
  25. }
  26. /// <summary>
  27. /// 更新监测计划
  28. /// </summary>
  29. /// <param name="input"></param>
  30. /// <returns></returns>
  31. public async Task Update(UpdateExamPlanInput input)
  32. {
  33. if (!await rep.AnyAsync(t => t.Id == input.Id))
  34. {
  35. throw Oops.Oh(ErrorCode.E2001);
  36. }
  37. var item = input.Adapt<ExamPlan>();
  38. await item.UpdateIncludeAsync([nameof(item.Name), nameof(item.FullName), nameof(item.ShortName), nameof(item.Remark), nameof(item.Config)]);
  39. }
  40. /// <summary>
  41. /// 删除监测计划
  42. /// </summary>
  43. /// <param name="input"></param>
  44. /// <returns></returns>
  45. public async Task Del(BaseId input)
  46. {
  47. var item = await rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  48. if (item.Status == ExamStatus.ACTIVE || item.Status == ExamStatus.STOPPED)
  49. {
  50. throw Oops.Oh(ErrorCode.E3001, "已使用监测计划");
  51. }
  52. await item.DeleteAsync();
  53. }
  54. #endregion
  55. #region 状态变更
  56. /// <summary>
  57. /// 开始监测
  58. /// </summary>
  59. /// <param name="input"></param>
  60. /// <returns></returns>
  61. public async Task Start(BaseId input)
  62. {
  63. var item = await rep.Include(t => t.ExamOrgs).FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  64. if (item.Status != ExamStatus.READY)
  65. {
  66. throw Oops.Oh(ErrorCode.E2006);
  67. }
  68. if (!item.ExamOrgs.Any())
  69. {
  70. throw Oops.Oh(ErrorCode.E2007, "监测机构");
  71. }
  72. item.Status = ExamStatus.ACTIVE;
  73. item.BeginTime = DateTime.Now;
  74. await item.UpdateIncludeAsync(new[] { nameof(item.Status), nameof(item.BeginTime) });
  75. }
  76. /// <summary>
  77. /// 结束监测
  78. /// </summary>
  79. /// <param name="input"></param>
  80. /// <returns></returns>
  81. public async Task Stop(BaseId input)
  82. {
  83. var item = await rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  84. if (item.Status != ExamStatus.ACTIVE)
  85. {
  86. throw Oops.Oh(ErrorCode.E2006);
  87. }
  88. item.Status = ExamStatus.STOPPED;
  89. item.EndTime = DateTime.Now;
  90. await item.UpdateIncludeAsync(new[] { nameof(item.Status), nameof(item.EndTime) });
  91. }
  92. /// <summary>
  93. /// 取消监测
  94. /// </summary>
  95. /// <param name="input"></param>
  96. /// <returns></returns>
  97. public async Task Cancel(BaseId input)
  98. {
  99. var item = await rep.FirstOrDefaultAsync(t => t.Id == input.Id) ?? throw Oops.Oh(ErrorCode.E2001);
  100. if (item.Status == ExamStatus.ACTIVE)
  101. {
  102. throw Oops.Oh(ErrorCode.E2006);
  103. }
  104. item.Status = ExamStatus.CANCELLED;
  105. item.EndTime = DateTime.Now;
  106. await item.UpdateIncludeAsync(new[] { nameof(item.Status), nameof(item.EndTime) });
  107. }
  108. #endregion
  109. #region 查询统计
  110. /// <summary>
  111. /// 根据ID获取监测计划
  112. /// </summary>
  113. /// <param name="id"></param>
  114. /// <returns></returns>
  115. public async Task<ExamPlanOutput> GetById(int id)
  116. {
  117. var item = await rep.DetachedEntities.ProjectToType<ExamPlanOutput>()
  118. .FirstOrDefaultAsync(t => t.Id == id) ?? throw Oops.Oh(ErrorCode.E2001);
  119. return item;
  120. //return item.Adapt<ExamPlanOutput>();
  121. }
  122. /// <summary>
  123. /// 获取监测计划抽样状态
  124. /// </summary>
  125. /// <param name="id"></param>
  126. /// <returns></returns>
  127. public async Task<ExamPlanSampleStatusOutput> GetSampleStatusById(int id)
  128. {
  129. var sampleStatus = (await rep.DetachedEntities.FirstOrDefaultAsync(t => t.Id == id))?.SampleStatus ?? throw Oops.Oh(ErrorCode.E2001);
  130. return new() { Id = id, SampleStatus = sampleStatus };
  131. }
  132. /// <summary>
  133. /// 分页查询监测计划列表
  134. /// </summary>
  135. /// <param name="input"></param>
  136. /// <returns></returns>
  137. public async Task<PageResult<ExamPlanOutput>> QueryPageList(ExamPlanPageInput input)
  138. {
  139. var query = GetQueryBase(input);
  140. var ret = await query.OrderByDescending(t => t.CreateTime).ProjectToType<ExamPlanOutput>().ToADPagedListAsync(input.PageIndex, input.PageSize);
  141. return ret;
  142. }
  143. /// <summary>
  144. /// 获取我的单据状态数量
  145. /// </summary>
  146. /// <returns></returns>
  147. public async Task<List<StatusCount>> QueryStatusCount(ExamPlanPageInput input)
  148. {
  149. var query = GetQueryBase(input);
  150. if (query == null)
  151. {
  152. return [];
  153. }
  154. var counts = await query.GroupBy(t => t.Status).Select(t => new StatusCount { Status = (int)t.Key, Count = t.Count() }).ToListAsync();
  155. return counts;
  156. }
  157. /// <summary>
  158. /// 获取最近5个抽测参照成绩监测计划
  159. /// </summary>
  160. /// <param name="id"></param>
  161. /// <returns></returns>
  162. public async Task<List<ExamPlanOutput>> GetSampleRefPlanList(int id)
  163. {
  164. var examPlan = await rep.DetachedEntities.FirstOrDefaultAsync(t => t.Id == id) ?? throw Oops.Oh(ErrorCode.E2001);
  165. var items = await rep.DetachedEntities.Where(t => t.Id < id && t.EducationStage == examPlan.EducationStage)
  166. .OrderByDescending(t => t.SemesterId).ThenByDescending(t => t.Id)
  167. .Take(5)
  168. .ProjectToType<ExamPlanOutput>()
  169. .ToListAsync();
  170. return items;
  171. }
  172. #endregion
  173. #region 私有方法
  174. /// <summary>
  175. /// 构建查询
  176. /// </summary>
  177. /// <param name="input"></param>
  178. /// <returns></returns>
  179. private IQueryable<ExamPlan> GetQueryBase(ExamPlanPageInput input)
  180. {
  181. var name = !string.IsNullOrEmpty(input.Name?.Trim());
  182. var searchBeginTime = !string.IsNullOrEmpty(input.SearchBeginTime?.Trim());
  183. var searchEndTime = !string.IsNullOrEmpty(input.SearchEndTime?.Trim());
  184. var query = rep.DetachedEntities.Where((name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%") || EF.Functions.Like(u.FullName, $"%{input.Name.Trim()}%") || EF.Functions.Like(u.ShortName, $"%{input.Name.Trim()}%")))
  185. .Where(input.EducationStage.HasValue, t => t.EducationStage == input.EducationStage)
  186. //.Where(input.ExamPeriodType.HasValue, t => t.ExamPeriodType == input.ExamPeriodType)
  187. //.Where(input.ExamType.HasValue, t => t.ExamType == input.ExamType)
  188. .Where(input.SemesterId.HasValue, t => t.SemesterId == input.SemesterId)
  189. .Where(input.Status.HasValue, t => t.Status == input.Status)
  190. .Where((searchBeginTime, u => u.CreateTime >= DateTime.Parse(input.SearchBeginTime)))
  191. .Where((searchEndTime, u => u.CreateTime <= DateTime.Parse(input.SearchEndTime)));
  192. return query;
  193. }
  194. #endregion
  195. }