lrf402788946 4 years ago
parent
commit
b8d66f6a0f
2 changed files with 118 additions and 25 deletions
  1. 1 1
      app/controller/apply.js
  2. 117 24
      app/service/apply.js

+ 1 - 1
app/controller/apply.js

@@ -17,7 +17,7 @@ class ApplyController extends Controller {
     this.ctx.ok({ data });
   }
   async arrange() {
-    const data = await this.service.arrangeteacher(this.ctx.query);
+    const data = await this.service.arrangeteacher(this.ctx.request.body);
     this.ctx.ok({ data });
   }
 }

+ 117 - 24
app/service/apply.js

@@ -36,8 +36,13 @@ class ApplyService extends CrudService {
     return teachers;
   }
 
-  // 教师计划初步课表安排,可反复使用
-  async arrangeteacher({ planid }) {
+  /**
+   * 教师计划初步课表安排,可反复使用
+   * @param {Object} body planid:计划id,ids:期数id列表;classtype:班级类型
+   */
+  async arrangeteacher({ planid, ids, classtype }) {
+    console.log(classtype);
+    assert(planid, '缺少计划信息');
     const trainplan = await this.trainmodel.findById(planid);
     if (!trainplan) {
       throw new BusinessError(ErrorCode.DATA_EXISTED, '年度计划不存在');
@@ -62,9 +67,25 @@ class ApplyService extends CrudService {
     const afterList = [];
     // 排课
     for (const l of arr) {
-      const { termid, subid, day: date, teaid, status, batchid } = l;
-      // 本期超过2次的教师列表,如果没有人就用这里分最高的排
-      let outTwoTimesList = [];
+      const { termid, subid, day: date, status, type, classid } = l;
+      // 检验是否在需要安排的期内
+      if (!ids.includes(termid)) {
+        // 不在要求安排的期内,就直接放回去
+        afterList.push(l);
+        continue;
+      }
+      // 检查是否符合要求的班级类型
+      if (classtype || `${classtype}` === '0') {
+        // 不符合,放回去,下一个
+        if (`${classtype}` !== `${type}`) {
+          afterList.push(l);
+          continue;
+        }
+      }
+      // 重置教师
+      l.teaid = null;
+      l.teaname = null;
+
       if (status && `${status}` === '1') {
         afterList.push(l);
         continue;
@@ -94,22 +115,35 @@ class ApplyService extends CrudService {
       applyList = applyList.filter(f => f.score);
       // 按成绩排序
       applyList = _.orderBy(applyList, [ 'score' ], [ 'desc' ]);
+      // 本期超过2次的教师列表,如果没有人就用这里分最高的排 + 教过这个班的教师列表,不过内容都一样
+      let outTwoTimesList = [];
       // 依次循环申请的教师列表,往这个课程安排中放教师
       for (const atea of applyList) {
-        // 先查询,该教师,是否在今天有安排
+        // 先查询,该教师,是否在今天有安排 条件1:同一天,一个教师只能有一次,因为一上一天课
         const tr = afterList.find(
           f => f.teaid === atea.teacherid && f.day === atea.date
         );
         if (tr) continue;
+        // 条件2:优先排一期2次以内的教师,超过2次的教师延后排,根据 次数升序,分数降序找合适的;
         // 查看这期内,每个申请上课的教师时候超过2天(2条记录),如果超过,则不排,但是如果最后没有人了,就得硬排了
         const r = afterList.filter(
           f => f.termid === termid && f.teaid === atea.teacherid
         );
 
         if (r.length >= 2) {
-          outTwoTimesList = [ ...outTwoTimesList, atea ];
+          // 需要记录这个老师已经有几次
+          const obj = { ...atea, times: r.length };
+          outTwoTimesList = [ ...outTwoTimesList, obj ];
           continue;
         } else {
+          // 条件3:尽量不让一个教师在一个班出现2次及其以上,但是如果没人,之前又排完了,还是会出现一个教师教1个班2天的情况,所以需要最后收尾检查
+          const alreadyTeach = afterList.find(f => f.classid === classid && f.teaid === atea.teacherid);
+          if (alreadyTeach) {
+            // 已经教过这个班了,也暂时放到2次以上列表中,将次数记录下来
+            const obj = { ...atea, times: r.length };
+            outTwoTimesList = [ ...outTwoTimesList, obj ];
+            continue;
+          }
           l.teaid = atea.teacherid;
           l.teaname = atea.teaname;
           break;
@@ -117,9 +151,15 @@ class ApplyService extends CrudService {
       }
       // 检查,该天,该科的课是否有教师
       const has_teaid = _.get(l, 'teaid');
+
       if (!has_teaid) {
-      //   // 如果没有教师,就需要在outTowTimesList列表中找分最高的教师
-        const list = _.orderBy(outTwoTimesList, [ 'score' ], [ 'desc' ]);
+        // 如果没有教师,就需要在outTowTimesList列表中找分最高的教师
+        // 排序需要根据,次数(后加的),分数排序,优先选次数最少,分数最高的教师
+        const list = _.orderBy(
+          outTwoTimesList,
+          [ 'times', 'score' ],
+          [ 'asc', 'desc' ]
+        );
         for (const i of list) {
           const tr = afterList.find(
             f => f.teaid === i.teacherid && f.day === i.date
@@ -135,6 +175,18 @@ class ApplyService extends CrudService {
       afterList.push(l);
     }
     // 将afterList还原回正常的termnum;
+    // const test = afterList.filter(f => ids.includes(f.termid) && f.type === classtype && f.teaid);
+    // const test2 = _.groupBy(test, 'name');
+    // const keys = Object.keys(test2);
+    // console.log(test);
+    // for (const key of keys) {
+    //   console.group(`${key}班`);
+    //   for (const t of test2[key]) {
+    //     console.log(`${t.day}-${t.subname}-${t.teaname}`);
+    //   }
+    //   console.groupEnd();
+    // }
+
     const newTermnum = this.returnTermnum(afterList, termnum);
     // 保存至计划
     trainplan.termnum = newTermnum;
@@ -142,7 +194,6 @@ class ApplyService extends CrudService {
   }
   // 确认计划安排
   async arrangeConfirm({ planid, ids, classtype }) {
-    console.log(planid, ids, classtype);
     const trainplan = await this.trainmodel.findById(planid);
     if (!trainplan) {
       throw new BusinessError(ErrorCode.DATA_EXISTED, '年度计划不存在');
@@ -163,7 +214,7 @@ class ApplyService extends CrudService {
         if (!(b.class && _.isArray(b.class))) continue;
         for (const c of b.class) {
           // 检查是否要求班级类型
-          if (classtype) {
+          if (classtype || `${classtype}` === '0') {
             // 获取这个班级的班级类型
             const { type } = c;
             // 判断班级类型与要求的符不符合,不符合就跳过不改
@@ -181,7 +232,6 @@ class ApplyService extends CrudService {
     await trainplan.save();
   }
 
-
   /**
    * 拍平了的课表=>termnum
    * @param {Array} list 拍平了的课表,详情参考页面的初步课表的数据
@@ -290,7 +340,6 @@ class ApplyService extends CrudService {
     return arr;
   }
 
-
   /**
    * 发送消息
    * @param {Object} param planid:年度计划id,ids,发送的期列表;classtype:发送班级类型 undefined 都发,有的话就找指定班级类型发
@@ -318,14 +367,24 @@ class ApplyService extends CrudService {
     // 找到教师用户信息
     let teauserList = await this.umodel.find({ uid: teaids });
     if (teaList) teaList = JSON.parse(JSON.stringify(teaList));
-    if (teauserList)teauserList = JSON.parse(JSON.stringify(teauserList));
+    if (teauserList) teauserList = JSON.parse(JSON.stringify(teauserList));
     // 发送,此处是根据安排,给教师发.还有一种方案是根据教师,整理安排一起发送
     // 查询是否发送过这期的通知
     // 排序
     arr = _.orderBy(arr, [ 'day' ], [ 'asc' ]);
     for (const l of arr) {
       // 教师id,期数,班级名,上课的日期,课程名
-      const { teaid, term, name, day, subname, termid, classid, type, status } = l;
+      const {
+        teaid,
+        term,
+        name,
+        day,
+        subname,
+        termid,
+        classid,
+        type,
+        status,
+      } = l;
       // 已确认的教师不发信息
       if (status === '1') continue;
       // 判断发送的班级类型
@@ -343,10 +402,15 @@ class ApplyService extends CrudService {
       let tourl;
       let to_send = false;
       if (openid) {
-        let notice = await this.nmodel.findOne({ planid, termid, classid, type: '6' });
+        let notice = await this.nmodel.findOne({
+          planid,
+          termid,
+          classid,
+          type: '6',
+        });
         // 找下是否发过信息
         if (notice) {
-        // 发过信息,找有没有这个教师
+          // 发过信息,找有没有这个教师
           const { notified } = notice;
           if (_.isArray(notified)) {
             const has_notice = notified.find(f => f.notifiedid === teaid);
@@ -354,20 +418,51 @@ class ApplyService extends CrudService {
               const { status } = has_notice;
               if (status !== '1') to_send = true;
             } else {
-              const obj = { notifiedid: teaid, username: _.get(tea, 'name', ''), content: msg };
+              const obj = {
+                notifiedid: teaid,
+                username: _.get(tea, 'name', ''),
+                content: msg,
+              };
               notice.notified.push(obj);
               await notice.save();
               to_send = true;
             }
           }
         } else {
-          const notified = [{ notifiedid: teaid, username: _.get(tea, 'name', ''), content: msg }];
-          const noticeObj = { planyearid, planid, termid, classid, noticeid: 'system', type: '6', content: `${term}期-${name.includes('班') ? name : `${name}班`}教师计划初步信息确认`, notified };
+          const notified = [
+            {
+              notifiedid: teaid,
+              username: _.get(tea, 'name', ''),
+              content: msg,
+            },
+          ];
+          const noticeObj = {
+            planyearid,
+            planid,
+            termid,
+            classid,
+            noticeid: 'system',
+            type: '6',
+            content: `${term}期-${
+              name.includes('班') ? name : `${name}班`
+            }教师计划初步信息确认`,
+            notified,
+          };
           await this.nmodel.create(noticeObj);
-          notice = await this.nmodel.findOne({ planid, termid, classid, type: '6' });
+          notice = await this.nmodel.findOne({
+            planid,
+            termid,
+            classid,
+            type: '6',
+          });
           to_send = true;
         }
-        tourl = this.ctx.app.config.baseUrl + '/msgconfirm/?userid=' + teaid + '&noticeid=' + notice._id;
+        tourl =
+          this.ctx.app.config.baseUrl +
+          '/msgconfirm/?userid=' +
+          teaid +
+          '&noticeid=' +
+          notice._id;
       }
       if (to_send) {
         // 邮箱与微信都发送
@@ -379,8 +474,6 @@ class ApplyService extends CrudService {
           this.toSendWxMsg(openid, msg, tea.name, tourl);
         }
       }
-
-
     }
   }
   /**