浏览代码

自动排初步计划教师

lrf402788946 4 年之前
父节点
当前提交
7f918caaf1
共有 4 个文件被更改,包括 198 次插入40 次删除
  1. 4 0
      app/controller/.teacher.js
  2. 25 27
      app/controller/.teaplan.js
  3. 2 0
      app/router.js
  4. 167 13
      app/service/teaplan.js

+ 4 - 0
app/controller/.teacher.js

@@ -153,4 +153,8 @@ module.exports = {
     requestBody: ["ids"],
     requestBody: ["ids"],
     service: "fetchteachers",
     service: "fetchteachers",
   },
   },
+  checkarrange: {
+    requestBody: ["id",'date'],
+    service: "checkarrange",
+  },
 };
 };

+ 25 - 27
app/controller/.teaplan.js

@@ -1,46 +1,44 @@
 module.exports = {
 module.exports = {
   create: {
   create: {
-    requestBody: [
-      '!trainplanid',
-      'nodate',
-      'classid',
-      'headteacherid'
-    ]
+    requestBody: ["!trainplanid", "nodate", "classid", "headteacherid"],
   },
   },
   destroy: {
   destroy: {
-    params: ['!id'],
-    service: 'delete'
+    params: ["!id"],
+    service: "delete",
   },
   },
   update: {
   update: {
-    params: ['!id'],
-    requestBody: [
-      'trainplanid',
-      'nodate',
-      'classid',
-      'headteacherid'
-    ]
+    params: ["!id"],
+    requestBody: ["trainplanid", "nodate", "classid", "headteacherid"],
   },
   },
   show: {
   show: {
     parameters: {
     parameters: {
-      params: ['!id']
+      params: ["!id"],
     },
     },
-    service: 'fetch'
+    service: "fetch",
   },
   },
   index: {
   index: {
     parameters: {
     parameters: {
       query: {
       query: {
-        trainplanid :'trainplanid',
-        nodate:'nodate',
-        classid :'classid',
-        headteacherid :'headteacherid'
-      }
+        trainplanid: "trainplanid",
+        nodate: "nodate",
+        classid: "classid",
+        headteacherid: "headteacherid",
+      },
     },
     },
-    service: 'query',
+    service: "query",
     options: {
     options: {
-      query: ['skip', 'limit'],
-      sort: ['meta.createdAt'],
+      query: ["skip", "limit"],
+      sort: ["meta.createdAt"],
       desc: true,
       desc: true,
-      count: true
-    }
+      count: true,
+    },
+  },
+  arrange: {
+    parameters: {
+      query: {
+        planid: "planid",
+      },
+    },
+    service: "arrangeteacher",
   },
   },
 };
 };

+ 2 - 0
app/router.js

@@ -297,6 +297,8 @@ module.exports = app => {
     '/api/train/teaplan/update/:id',
     '/api/train/teaplan/update/:id',
     controller.teaplan.update
     controller.teaplan.update
   );
   );
+  // 计划自动排教师
+  router.get('teaplan', '/api/train/teaplan/arrange', controller.teaplan.arrange);
 
 
   // 教师申请讲课表设置路由
   // 教师申请讲课表设置路由
   router.get(
   router.get(

+ 167 - 13
app/service/teaplan.js

@@ -16,6 +16,8 @@ class TeaplanService extends CrudService {
     this.tmodel = this.ctx.model.Trainplan;
     this.tmodel = this.ctx.model.Trainplan;
     this.cmodel = this.ctx.model.Class;
     this.cmodel = this.ctx.model.Class;
     this.dmodel = this.ctx.model.Department;
     this.dmodel = this.ctx.model.Department;
+    this.submodel = this.ctx.model.Subject;
+    this.teamodel = this.ctx.model.Teacher;
   }
   }
 
 
   // 查询所有班主任带是否能带班标记
   // 查询所有班主任带是否能带班标记
@@ -29,25 +31,40 @@ class TeaplanService extends CrudService {
     }
     }
     const term = await trainplan.termnum.id(termid);
     const term = await trainplan.termnum.id(termid);
     if (!term) {
     if (!term) {
-      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '全年计划内期信息不存在');
+      throw new BusinessError(
+        ErrorCode.DATA_NOT_EXIST,
+        '全年计划内期信息不存在'
+      );
     }
     }
     const batch = await term.batchnum.id(batchid);
     const batch = await term.batchnum.id(batchid);
     if (!batch) {
     if (!batch) {
-      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '全年计划内批次信息不存在');
+      throw new BusinessError(
+        ErrorCode.DATA_NOT_EXIST,
+        '全年计划内批次信息不存在'
+      );
     }
     }
     const newheadteachers = [];
     const newheadteachers = [];
     // 遍历班主任信息
     // 遍历班主任信息
     for (const headteacher of headteachers) {
     for (const headteacher of headteachers) {
       // 查询某班主任对应的班主任全年计划表
       // 查询某班主任对应的班主任全年计划表
-      const teaplan = await this.model.findOne({ headteacherid: headteacher.id });
+      const teaplan = await this.model.findOne({
+        headteacherid: headteacher.id,
+      });
       if (teaplan) {
       if (teaplan) {
         // 取得所有不能排班的日期列表
         // 取得所有不能排班的日期列表
         const nodates = teaplan.nodate;
         const nodates = teaplan.nodate;
-        const iswork = await this.teacheriswork(nodates, batch.startdate, batch.enddate);
+        const iswork = await this.teacheriswork(
+          nodates,
+          batch.startdate,
+          batch.enddate
+        );
         if (iswork) {
         if (iswork) {
           newheadteachers.push(headteacher);
           newheadteachers.push(headteacher);
         } else {
         } else {
-          newheadteachers.push({ ...JSON.parse(JSON.stringify(headteacher)), disabled: true });
+          newheadteachers.push({
+            ...JSON.parse(JSON.stringify(headteacher)),
+            disabled: true,
+          });
         }
         }
       } else {
       } else {
         newheadteachers.push(headteacher);
         newheadteachers.push(headteacher);
@@ -102,18 +119,30 @@ class TeaplanService extends CrudService {
     // 将全年计划中的批次信息取出放在一个数组中
     // 将全年计划中的批次信息取出放在一个数组中
     for (const term of trainplan.termnum) {
     for (const term of trainplan.termnum) {
       for (const batch of term.batchnum) {
       for (const batch of term.batchnum) {
-        const teaListAll = _.cloneDeep(JSON.parse(JSON.stringify(headteacherList)));
+        const teaListAll = _.cloneDeep(
+          JSON.parse(JSON.stringify(headteacherList))
+        );
         for (const teaplan of teaplanList) {
         for (const teaplan of teaplanList) {
-          if (teaplan.nodate && (teaplan.nodate).length > 0) {
+          if (teaplan.nodate && teaplan.nodate.length > 0) {
             // 遍历班主任全年计划表中的不能上课的日期
             // 遍历班主任全年计划表中的不能上课的日期
             for (const nodate of teaplan.nodate) {
             for (const nodate of teaplan.nodate) {
-            // 如果不能上课的日期在该批次的开始时间和结束时间中,将该班主任从班主任列表中删除
-              if (moment(nodate).isBetween(batch.startdate, batch.enddate, null, '[]')) {
+              // 如果不能上课的日期在该批次的开始时间和结束时间中,将该班主任从班主任列表中删除
+              if (
+                moment(nodate).isBetween(
+                  batch.startdate,
+                  batch.enddate,
+                  null,
+                  '[]'
+                )
+              ) {
                 // const headteacher_ = await this.hmodel.findById(teaplan.headteacherid);
                 // const headteacher_ = await this.hmodel.findById(teaplan.headteacherid);
                 // if (headteacher_) {
                 // if (headteacher_) {
                 //   teaListAll.push(headteacher_);
                 //   teaListAll.push(headteacher_);
                 // }
                 // }
-                _.remove(teaListAll, item => item.id === teaplan.headteacherid);
+                _.remove(
+                  teaListAll,
+                  item => item.id === teaplan.headteacherid
+                );
               }
               }
             }
             }
           }
           }
@@ -138,7 +167,9 @@ class TeaplanService extends CrudService {
           let index = 0;
           let index = 0;
           for (const _tea of teaListAll_) {
           for (const _tea of teaListAll_) {
             // 过滤出当前教师的部门和部门可用人数
             // 过滤出当前教师的部门和部门可用人数
-            const deptinfo = _.find(departmentList, function(o) { return o.deparmentid === _tea.department; });
+            const deptinfo = _.find(departmentList, function(o) {
+              return o.deparmentid === _tea.department;
+            });
             if (deptinfo.dcount - index > 1) {
             if (deptinfo.dcount - index > 1) {
               _class.headteacherid = _tea.id;
               _class.headteacherid = _tea.id;
               _.remove(teaListAll_, item => item.id === _tea.id);
               _.remove(teaListAll_, item => item.id === _tea.id);
@@ -176,14 +207,137 @@ class TeaplanService extends CrudService {
     departmentList = _.uniqWith(departmentList, _.isEqual);
     departmentList = _.uniqWith(departmentList, _.isEqual);
     for (const department of departmentList) {
     for (const department of departmentList) {
       // 计算出能该批次能上课的班主任中各部门有多少人
       // 计算出能该批次能上课的班主任中各部门有多少人
-      const dnum = _.filter(teaList, item => item.department === department.deparmentid).length;
+      const dnum = _.filter(
+        teaList,
+        item => item.department === department.deparmentid
+      ).length;
       department.dnum = dnum;
       department.dnum = dnum;
       // 计算出各部门有多少人
       // 计算出各部门有多少人
-      const dcount = await this.hmodel.count({ department: department.deparmentid });
+      const dcount = await this.hmodel.count({
+        department: department.deparmentid,
+      });
       department.dcount = dcount;
       department.dcount = dcount;
     }
     }
     return departmentList;
     return departmentList;
   }
   }
+
+  async arrangeteacher({ planid }) {
+    const trainplan = await this.tmodel.findOne({ id: planid });
+    if (!trainplan) { throw new BusinessError(ErrorCode.DATA_EXISTED, '年度计划不存在'); }
+    // 查找所有教师列表
+    const teacherList = await this.teamodel.find();
+    // 查找所有教师上报列表
+    const teaplanList = await this.model.find();
+    // 课程
+    const subjectList = await this.submodel.find();
+    const termList = _.cloneDeep(trainplan.termnum);
+    const { termnum } = termList;
+    if (!termnum) return;
+    // 整理出课表
+    const arr = [];
+    for (const t of termnum) {
+      const { batchnum, term, _id: termid } = t;
+      // 班级和课程一一匹配显示在列表上
+      for (const b of batchnum) {
+        const { class: classes, lessons, startdate, enddate, _id: batchid } = b;
+        const claslesList = this.setList(term, termid, batchid, classes, lessons);
+        arr.push(...claslesList);
+      }
+    }
+    // 安排后的课表
+    const afterList = [];
+    // 排课
+    for (const l of arr) {
+      const { termid, subid, day: date, teaid } = l;
+      if (teaid) { afterList.push(l); continue; }
+      const subject = subjectList.find(f => ObjectId(subid).equals(f._id));
+      if (subject.need_teacher !== '0') continue;
+      // 申请该天,该科目的教师,并查出教师的名字,分数;并按分数排序
+      let applyList = teaplanList.filter(f => f.termid === termid && f.subid === subid && f.date === date);
+      applyList = applyList.map(i => {
+        const r = this.teacherList.find(f => ObjectId(i.teacherid).equals(f._id));
+        if (r) {
+          const { name: teaname, xsscore: score } = r;
+          i.teaname = teaname;
+          i.score = score * 1;
+        }
+        return i;
+      });
+      applyList = _.orderBy(applyList, [ 'score' ], [ 'desc' ]);
+      // 依次循环申请的教师列表,往这个课程安排中放教师
+      for (const atea of applyList) {
+        // 先查询,该教师,是否在今天有安排
+        const tr = afterList.find(f => f.teaid === atea.teacherid && f.day === atea.date);
+        if (tr) continue;
+        else {
+          l.teaid = tr.teacherid;
+          l.teaname = tr.teaname;
+          break;
+        }
+      }
+      afterList.push(l);
+    }
+    // 将afterList还原回正常的termnum
+    let newTermnum = [];
+    for (const l of afterList) {
+      const { termid, batchid, classid, ...info } = l;
+      const updata = _.pick(info, [ 'day', 'subid', 'subname', 'teaid', 'teaname', 'time' ]);
+      newTermnum = trainplan.termnum.map(t => {
+        // 找到期
+        if (ObjectId(termid).equals(t._id)) {
+          t.batchnum = t.batchnum.map(b => {
+            if (ObjectId(batchid).equals(b._id)) {
+              // 找到批次
+              b.class = b.class.map(c => {
+                if (ObjectId(classid).equals(c._id)) {
+                  if (c.lessons) {
+                    // 说明有课程安排,找有没有重复的,没有就推进去,有就更改,subid查
+                    const r = c.lessons.find(f => f.subid === updata.subid);
+                    if (r) {
+                      const rindex = c.lessons.findIndex(
+                        f => f.subid === updata.subid
+                      );
+                      c.lessons[rindex] = updata;
+                    } else {
+                      c.lessons.push(updata);
+                    }
+                  } else {
+                    // 说明没有课程安排,放进去一条保存
+                    c.lessons = [ updata ];
+                  }
+                }
+                return c;
+              });
+            }
+            return b;
+          });
+        }
+        return t;
+      });
+    }
+    // 保存至计划
+    trainplan.termnum = newTermnum;
+    return await trainplan.save();
+  }
+
+
+  setList(term, termid, batchid, classes, lessonTemplate) {
+    const arr = [];
+    // 班级和课程匹配
+    for (const cla of classes) {
+      cla.term = term;
+      cla.termid = termid;
+      cla.batchid = batchid;
+      const { lessons } = cla;
+      if (!lessons) cla.lessons = lessonTemplate;
+      cla.lessons.map(i => {
+        let obj = _.omit(cla, [ 'lessons' ]);
+        obj = { ...obj, ...i, classid: _.clone(cla._id) };
+        arr.push(obj);
+      });
+    }
+    return arr;
+  }
 }
 }
 
 
 module.exports = TeaplanService;
 module.exports = TeaplanService;