teaplan.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. 'use strict';
  2. const assert = require('assert');
  3. const _ = require('lodash');
  4. const { ObjectId } = require('mongoose').Types;
  5. const { CrudService } = require('naf-framework-mongoose/lib/service');
  6. const { BusinessError, ErrorCode } = require('naf-core').Error;
  7. const moment = require('moment');
  8. class TeaplanService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'teaplan');
  11. this.model = this.ctx.model.Teaplan;
  12. this.hmodel = this.ctx.model.Headteacher;
  13. this.tmodel = this.ctx.model.Trainplan;
  14. this.cmodel = this.ctx.model.Class;
  15. this.dmodel = this.ctx.model.Department;
  16. }
  17. // async findteacher({ batchid }) {
  18. // // 查询所有班主任信息
  19. // const headteachers = await this.hmodel.find();
  20. // const newheadteachers = [];
  21. // // 遍历班主任信息
  22. // for (const headteacher of headteachers) {
  23. // // 查询某班主任对应的班主任全年计划表
  24. // const teaplan = await this.model.findOne({ headteacherid: headteacher.id });
  25. // if (teaplan) {
  26. // const nobatchids = teaplan.nobatchid;
  27. // // 如果有对应的全年计划表并且该计划表中的不能上课的批次包含指定批次,则添加status='0'的标记
  28. // if (nobatchids.includes(batchid)) {
  29. // newheadteachers.push({ ...JSON.parse(JSON.stringify(headteacher)), status: '0' });
  30. // } else {
  31. // newheadteachers.push(headteacher);
  32. // }
  33. // } else {
  34. // newheadteachers.push(headteacher);
  35. // }
  36. // }
  37. // return newheadteachers;
  38. // }
  39. async divide({ trainplanid }) {
  40. const data = [];
  41. // 根据全年计划表id查出对应的全年计划详细信息
  42. const trainplan = await this.tmodel.findById(trainplanid);
  43. // 将全年计划中的批次信息取出放在一个数组中
  44. const batchList = [];
  45. for (const term of trainplan.termnum) {
  46. for (const batch of term.batchnum) {
  47. batchList.push(batch);
  48. }
  49. }
  50. // 查询本培训计划中班主任全年计划表的全部信息
  51. const teaplanList = await this.model.find({ trainplanid });
  52. let noteaList = [];
  53. // 遍历所有批次信息
  54. for (const _batch of batchList) {
  55. // 遍历班主任全年计划表
  56. for (const teaplan of teaplanList) {
  57. // 过滤出已分配的数据中该班主任的数据
  58. const teaInfo = _.filter(data, item => item.headteacherid === teaplan.headteacherid);
  59. // 计算出每个班主任担任过班主任的次数
  60. teaplan.teacount = await this.cmodel.count({ headteacherid: teaplan.headteacherid }) + teaInfo.length;
  61. // 如果已分配的数据中该班主任的数据长度大于0
  62. if (teaInfo.length > 0) {
  63. // 遍历已分配的数据中该班主任的数据
  64. for (const _teaInfo of teaInfo) {
  65. // 查询该班主任已分配的数据中的班级信息
  66. const _class = await this.cmodel.findById(_teaInfo.classid);
  67. // 根据班级的批次id查出该班级的开始时间和结束时间
  68. const batchInfo = _.filter(batchList, item => item.id === _class.batchid);
  69. // 如果该班级的开始时间和结束时间于当前遍历批次的开始时间和结束时间有重合部分,将该班主任加入不能上课的班主任数组中
  70. if (await this.isrepeat(batchInfo.startdate, batchInfo.enddate, _batch.startdate, _batch.enddate)) {
  71. noteaList.push(teaplan);
  72. }
  73. }
  74. }
  75. // 遍历班主任全年计划表中的不能上课的日期
  76. for (const nodate of teaplan.nodate) {
  77. // 如果不能上课的日期在该批次的开始时间和结束时间中,将该班主任加入不能上课的班主任数组中
  78. if (moment(nodate).isBetween(_batch.startdate, _batch.enddate, null, '[]')) {
  79. noteaList.push(teaplan);
  80. }
  81. }
  82. }
  83. // 将数组去重
  84. noteaList = _.uniqWith(noteaList, _.isEqual);
  85. // 将班主任全年计划表过滤,去除在不能上课的班主任数组中已存在的数据
  86. let teaList = _.difference(teaplanList, noteaList);
  87. // 将不能上课的班主任数组清空
  88. noteaList = [];
  89. const departmentList = await this.departmentcount(teaList);
  90. for (const department of departmentList) {
  91. // 如果部门中人员的数量减去能部门中上课的班主任数量小于一,那么将能上课的班主任数组中部门为该部门的班主任移除一个
  92. if ((department.dcount - department.dnum) < 1) {
  93. let _noteaList = _.filter(teaList, item => item.deparmentid === department.deparmentid);
  94. _noteaList = _.orderBy(_noteaList, [ 'teacount' ], [ 'desc' ]);
  95. teaList = _.difference(teaList, _noteaList[0]);
  96. }
  97. }
  98. // 将该批次最终筛选出的能上课的班主任数组按每个班主任担任过班主任的次数倒序排序
  99. teaList = _.orderBy(teaList, [ 'teacount' ], [ 'asc' ]);
  100. // 查出该批次下所有的班级
  101. const classList = await this.cmodel.find({ batchid: _batch.id });
  102. // 循环该批次下所有的班级
  103. let index = 0;
  104. for (const _class of classList) {
  105. if (teaList[index]) {
  106. data.push({ classid: _class.id, headteacherid: teaList[index].headteacherid });
  107. } else {
  108. data.push({ classid: _class.id, headteacherid: undefined });
  109. }
  110. index = index + 1;
  111. }
  112. }
  113. return data;
  114. }
  115. // 判断两个时间段是否有重合部分
  116. async isrepeat(startdate1, enddate1, startdate2, enddate2) {
  117. let result = true;
  118. if (moment(enddate1).isSameOrBefore(startdate2)) {
  119. result = false;
  120. }
  121. if (moment(startdate1).isSameOrAfter(enddate2)) {
  122. result = false;
  123. }
  124. return result;
  125. }
  126. // 查询传递的班主任列表中每个部门的人数以及每个部门的总人数
  127. // teaList 传递的教师列表 dnum 传递的教师列表中各部门的人数 dcount 各部门的总人数
  128. async departmentcount(teaList) {
  129. let departmentList = [];
  130. for (const teaplan of teaList) {
  131. // 将班主任的部门放到一个数组中
  132. const headteacher = await this.hmodel.findById(teaplan.headteacherid);
  133. departmentList.push({ deparmentid: headteacher.department });
  134. teaplan.deparmentid = headteacher.department;
  135. }
  136. // 将数组去重
  137. departmentList = _.uniqWith(departmentList, _.isEqual);
  138. for (const department of departmentList) {
  139. // 计算出能该批次能上课的班主任中各部门有多少人
  140. const dnum = _.filter(teaList, item => item.deparmentid === department.deparmentid).length;
  141. department.dnum = dnum;
  142. // 计算出各部门有多少人
  143. const dcount = await this.hmodel.count({ department: department.deparmentid });
  144. department.dcount = dcount;
  145. }
  146. return departmentList;
  147. }
  148. }
  149. module.exports = TeaplanService;