SchoolClassService.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using Furion.DatabaseAccessor.Extensions;
  2. using YBEE.EQM.Core;
  3. namespace YBEE.EQM.Application;
  4. /// <summary>
  5. /// 学校班级信息管理服务
  6. /// </summary>
  7. public class SchoolClassService : ISchoolClassService, ITransient
  8. {
  9. private readonly IRepository<SchoolClass> _rep;
  10. public SchoolClassService(IRepository<SchoolClass> rep)
  11. {
  12. _rep = rep;
  13. }
  14. /// <summary>
  15. /// 添加学校班级
  16. /// </summary>
  17. /// <param name="input"></param>
  18. /// <returns></returns>
  19. public async Task Add(AddSchoolClassInput input)
  20. {
  21. if (!CurrentSysUserInfo.IsSuperAdmin)
  22. {
  23. input.SysOrgId = CurrentSysUserInfo.SysOrgId;
  24. }
  25. var check = await _rep.AnyAsync(t => t.SysOrgId == input.SysOrgId && t.EducationStage == input.EducationStage && t.GradeBeginYear == input.GradeBeginYear && t.ClassNumber == input.ClassNumber);
  26. if (check)
  27. {
  28. throw Oops.Oh(ErrorCode.E2003, "在同年级中", "班级号");
  29. }
  30. var item = input.Adapt<SchoolClass>();
  31. await item.InsertAsync();
  32. }
  33. /// <summary>
  34. /// 批量添加学校班级
  35. /// </summary>
  36. /// <param name="input"></param>
  37. /// <returns></returns>
  38. public async Task BatchAdd(BatchAddSchoolClassInput input)
  39. {
  40. if (!CurrentSysUserInfo.IsSuperAdmin)
  41. {
  42. input.SysOrgId = CurrentSysUserInfo.SysOrgId;
  43. }
  44. var maxClass = await _rep.Where(t => t.SysOrgId == input.SysOrgId && t.EducationStage == input.EducationStage && t.GradeBeginYear == input.GradeBeginYear).OrderByDescending(t => t.ClassNumber).FirstOrDefaultAsync();
  45. List<SchoolClass> newClass = new();
  46. for (short i = maxClass?.ClassNumber ?? 0; i < input.ClassCount;)
  47. {
  48. i++;
  49. var nc = input.Adapt<SchoolClass>();
  50. nc.Id = GetSchoolClassId(input.EducationStage, input.SysOrgId, input.GradeBeginYear, i);
  51. nc.ClassNumber = i;
  52. SetSchoolClassName(nc, input.EducationStage, input.GradeBeginYear, i);
  53. newClass.Add(nc);
  54. }
  55. }
  56. /// <summary>
  57. /// 获取批量导入班级ID
  58. /// </summary>
  59. /// <param name="input"></param>
  60. /// <returns></returns>
  61. public async Task<Dictionary<short, long>> GetImportSchoolClassList(ImportSchoolClassInput input)
  62. {
  63. var scs = await _rep.DetachedEntities.Where(t => t.SysOrgId == input.SysOrgId && t.EducationStage == input.ExamGrade.EducationStage && t.GradeBeginYear == input.ExamGrade.GradeBeginYear).ToListAsync();
  64. // 不存在的班级
  65. var newClassNumbers = (from c in input.ClassNumberList
  66. where !(from s in scs select s.ClassNumber).Contains(c)
  67. select c).ToList();
  68. // 已存在的班级
  69. Dictionary<short, long> ret = (from s in scs
  70. where input.ClassNumberList.Contains(s.ClassNumber)
  71. select s).ToDictionary(x => x.ClassNumber, y => y.Id);
  72. ret ??= new Dictionary<short, long>();
  73. // 添加不存在的班级
  74. List<SchoolClass> newClasses = new();
  75. foreach (var c in newClassNumbers)
  76. {
  77. long id = GetSchoolClassId(input.ExamGrade.EducationStage, input.SysOrgId, input.ExamGrade.GradeBeginYear, c);
  78. ret.Add(c, id);
  79. SchoolClass newItem = new()
  80. {
  81. Id = id,
  82. ClassNumber = c,
  83. SysOrgId = input.SysOrgId,
  84. SysOrgBranchId = input.SysOrgBranchId,
  85. EducationStage = input.ExamGrade.EducationStage,
  86. EducationYears = input.ExamGrade.EducationYears,
  87. GradeBeginYear = input.ExamGrade.GradeBeginYear,
  88. GradeEndYear = input.ExamGrade.GradeEndYear,
  89. };
  90. SetSchoolClassName(newItem, input.ExamGrade.EducationStage, input.ExamGrade.GradeBeginYear, c);
  91. newClasses.Add(newItem);
  92. }
  93. if (newClasses.Any())
  94. {
  95. await _rep.InsertNowAsync(newClasses);
  96. }
  97. return ret;
  98. }
  99. /// <summary>
  100. /// 批量插入班级
  101. /// </summary>
  102. /// <param name="schoolClasses"></param>
  103. /// <returns></returns>
  104. public async Task BatchInsert(List<BatchInsertSchoolClassInput> schoolClasses)
  105. {
  106. if(!schoolClasses.Any())
  107. {
  108. return;
  109. }
  110. var selectSqls = schoolClasses.Select(t =>
  111. {
  112. string sobid = "NULL";
  113. if (t.SysOrgBranchId.HasValue)
  114. {
  115. sobid = t.SysOrgBranchId.ToString();
  116. }
  117. string fullName = BuildFullName(t.EducationStage, t.GradeBeginYear, t.ClassNumber);
  118. string name = BuildName(t.GradeBeginYear, t.ClassNumber);
  119. string shortName = BuildShortName(t.ClassNumber);
  120. return @$"
  121. SELECT {t.Id} AS id, {t.SysOrgId} soid, {sobid} sobid, {(short)t.EducationYears} es, {t.ClassNumber} cn, '{name}' n, '{fullName}' fn, '{shortName}' sn, {t.GradeBeginYear} gby, {t.GradeEndYear} gey, {t.EducationYears} ey ";
  122. });
  123. string selectUnionAll = string.Join("UNION ALL", selectSqls);
  124. string insertSql = @$"
  125. INSERT INTO school_class(id, sys_org_id, sys_org_branch_id, education_stage, class_number, `name`, full_name, short_name, grade_begin_year, grade_end_year, education_years, `status`, create_sys_user_id, create_time, is_deleted)
  126. SELECT id, soid, sobid, es, cn, n, fn, sn, gby, gey, ey, 1, 2, CURRENT_TIMESTAMP, 0
  127. FROM
  128. ({selectUnionAll}
  129. ) AS SCS
  130. WHERE id NOT IN (SELECT id FROM school_class)
  131. ";
  132. await _rep.SqlNonQueryAsync(insertSql);
  133. }
  134. /// <summary>
  135. /// 获取班级信息
  136. /// </summary>
  137. /// <param name="sysOrgId"></param>
  138. /// <param name="sysOrgBranchId"></param>
  139. /// <param name="examGrade"></param>
  140. /// <param name="classNumber"></param>
  141. /// <returns></returns>
  142. public async Task<SchoolClassLiteOutput> GetSchoolClass(short sysOrgId, short? sysOrgBranchId, ExamGradeOutput examGrade, short classNumber)
  143. {
  144. var item = await _rep.DetachedEntities.FirstOrDefaultAsync(t => t.SysOrgId == sysOrgId && t.GradeBeginYear == examGrade.GradeBeginYear && t.ClassNumber == classNumber);
  145. if (item == null)
  146. {
  147. item = new()
  148. {
  149. Id = GetSchoolClassId(examGrade.EducationStage, sysOrgId, examGrade.GradeBeginYear, classNumber),
  150. ClassNumber = classNumber,
  151. SysOrgId = sysOrgId,
  152. SysOrgBranchId = sysOrgBranchId,
  153. EducationStage = examGrade.EducationStage,
  154. EducationYears = examGrade.EducationYears,
  155. GradeBeginYear = examGrade.GradeBeginYear,
  156. GradeEndYear = examGrade.GradeEndYear,
  157. };
  158. SetSchoolClassName(item, examGrade.EducationStage, examGrade.GradeBeginYear, classNumber);
  159. await item.InsertNowAsync();
  160. }
  161. return item.Adapt<SchoolClassLiteOutput>();
  162. }
  163. //public async Task<SchoolClassLiteOutput> GetSchoolClass(EducationStage educationStage, short sysOrgId, short? sysOrgBranchId, short gradeBeginYear, short classNumber){
  164. // var item = await _rep.DetachedEntities.FirstOrDefaultAsync(t => t.SysOrgId == sysOrgId && t.GradeBeginYear == gradeBeginYear && t.ClassNumber == classNumber);
  165. // if (item == null)
  166. // {
  167. // item = new()
  168. // {
  169. // Id = GetSchoolClassId(educationStage, sysOrgId, gradeBeginYear, classNumber),
  170. // ClassNumber = classNumber,
  171. // SysOrgId = sysOrgId,
  172. // SysOrgBranchId = sysOrgBranchId,
  173. // EducationStage = educationStage,
  174. // EducationYears = examGrade.EducationYears,
  175. // GradeBeginYear = examGrade.GradeBeginYear,
  176. // GradeEndYear = examGrade.GradeEndYear,
  177. // };
  178. // SetSchoolClassName(item, examGrade.EducationStage, examGrade.GradeBeginYear, classNumber);
  179. // await item.InsertAsync();
  180. // }
  181. // return item.Adapt<SchoolClassLiteOutput>();
  182. //}
  183. /// <summary>
  184. /// 获取班级ID
  185. /// </summary>
  186. /// <param name="educationStage">学段</param>
  187. /// <param name="sysOrgId">机构ID</param>
  188. /// <param name="gradeBeginYear">开始年份</param>
  189. /// <param name="classNumber">班号</param>
  190. /// <returns></returns>
  191. public long GetSchoolClassId(EducationStage educationStage, short sysOrgId, short gradeBeginYear, short classNumber)
  192. {
  193. return long.Parse($"{(short)educationStage}{sysOrgId.ToString().PadLeft(4, '0')}{gradeBeginYear.ToString().PadLeft(4, '0')}{classNumber.ToString().PadLeft(2, '0')}");
  194. }
  195. /// <summary>
  196. /// 根据ID获取学校班级信息
  197. /// </summary>
  198. /// <param name="id"></param>
  199. /// <returns></returns>
  200. public async Task<SchoolClassOutput> GetById(long id)
  201. {
  202. var item = await _rep.DetachedEntities.FirstOrDefaultAsync(x => x.Id == id) ?? throw Oops.Oh(ErrorCode.E2001);
  203. return item.Adapt<SchoolClassOutput>();
  204. }
  205. /// <summary>
  206. /// 根据级获取学校班级列表
  207. /// </summary>
  208. /// <param name="gradeBeginYear"></param>
  209. /// <returns></returns>
  210. public async Task<List<SchoolClassOutput>> GetListByGradeBeginYear(short gradeBeginYear)
  211. {
  212. if (!CurrentSysUserInfo.IsSuperAdmin && CurrentSysUserInfo.SysOrgId == 0)
  213. {
  214. return new();
  215. }
  216. var items = await _rep.DetachedEntities.Where(!CurrentSysUserInfo.IsSuperAdmin, t => t.SysOrgId == CurrentSysUserInfo.SysOrgId)
  217. .Where(gradeBeginYear != 0, t => t.GradeBeginYear == gradeBeginYear)
  218. .ProjectToType<SchoolClassOutput>().ToListAsync();
  219. return items;
  220. }
  221. /// <summary>
  222. /// 分页查询班级列表
  223. /// </summary>
  224. /// <param name="input"></param>
  225. /// <returns></returns>
  226. public async Task<PageResult<SchoolClassOutput>> QueryPageList(SchoolClassPageInput input)
  227. {
  228. var name = !string.IsNullOrEmpty(input.Name?.Trim());
  229. var ret = await _rep.DetachedEntities.Where((name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%")))
  230. .Where(input.SysOrgId.HasValue, t => t.SysOrgId == input.SysOrgId)
  231. .Where(input.SysOrgBranchId.HasValue, t => t.SysOrgBranchId == input.SysOrgBranchId)
  232. .Where(input.GradeBeginYear.HasValue, t => t.GradeBeginYear == input.GradeBeginYear)
  233. .Where(input.ClassNumber.HasValue, t => t.ClassNumber == input.ClassNumber)
  234. .Where(input.Status.HasValue, t => t.Status == input.Status)
  235. .Where(!CurrentSysUserInfo.IsSuperAdmin, t => t.SysOrgId == CurrentSysUserInfo.SysOrgId)
  236. .ProjectToType<SchoolClassOutput>()
  237. .ToADPagedListAsync(input.PageIndex, input.PageSize);
  238. return ret;
  239. }
  240. #region 私有方法
  241. /// <summary>
  242. /// 设置班级名称
  243. /// </summary>
  244. /// <param name="sc">班级实体</param>
  245. /// <param name="educationStage">学段</param>
  246. /// <param name="gradeBeginYear">开始年份</param>
  247. /// <param name="classNumber">班号</param>
  248. private static void SetSchoolClassName(SchoolClass sc, EducationStage educationStage, short gradeBeginYear, short classNumber)
  249. {
  250. sc.FullName = BuildFullName(educationStage, gradeBeginYear, classNumber);
  251. sc.Name = BuildName(gradeBeginYear, classNumber);
  252. sc.ShortName = BuildShortName(classNumber);
  253. }
  254. private static string BuildFullName(EducationStage educationStage, short gradeBeginYear, short classNumber)
  255. {
  256. return $"{educationStage.GetDescription()}{gradeBeginYear}级{classNumber}班";
  257. }
  258. private static string BuildName(short gradeBeginYear, short classNumber)
  259. {
  260. return $"{gradeBeginYear}级{classNumber}班";
  261. }
  262. private static string BuildShortName(short classNumber)
  263. {
  264. return $"{classNumber}班";
  265. }
  266. #endregion
  267. }