lrf402788946 %!s(int64=4) %!d(string=hai) anos
pai
achega
655ca2b52b
Modificáronse 3 ficheiros con 154 adicións e 26 borrados
  1. 6 1
      app/controller/.apply.js
  2. 2 0
      app/router.js
  3. 146 25
      app/service/apply.js

+ 6 - 1
app/controller/.apply.js

@@ -21,7 +21,7 @@ module.exports = {
       query: {
         termid: "termid",
         subid: "subid",
-        date:"date",
+        date: "date",
         teacherid: "teacherid",
         reason: "reason",
       },
@@ -34,4 +34,9 @@ module.exports = {
       count: true,
     },
   },
+  sendmsg: {
+    params: ["!planid"],
+    requestBody: ["ids"],
+    service: "arrangeSendMsg",
+  },
 };

+ 2 - 0
app/router.js

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

+ 146 - 25
app/service/apply.js

@@ -4,6 +4,7 @@
 const assert = require('assert');
 const { after } = require('lodash');
 const _ = require('lodash');
+const moment = require('moment');
 const { ObjectId } = require('mongoose').Types;
 const { CrudService } = require('naf-framework-mongoose/lib/service');
 const { BusinessError, ErrorCode } = require('naf-core').Error;
@@ -15,6 +16,7 @@ class ApplyService extends CrudService {
     this.tmodel = this.ctx.model.Teacher;
     this.submodel = this.ctx.model.Subject;
     this.trainmodel = this.ctx.model.Trainplan;
+    this.dayList = [ '日', '一', '二', '三', '四', '五', '六' ];
   }
 
   // 查询
@@ -32,6 +34,7 @@ class ApplyService extends CrudService {
     return teachers;
   }
 
+  // 教师计划初步课表安排,可反复使用
   async arrangeteacher({ planid }) {
     const trainplan = await this.trainmodel.findById(planid);
     if (!trainplan) {
@@ -52,22 +55,7 @@ class ApplyService extends CrudService {
     if (!termnum) return;
     termnum = JSON.parse(JSON.stringify(termnum));
     // 整理出课表
-    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 arr = this.setLessonList(termnum);
     // 安排后的课表
     const afterList = [];
     // 排课
@@ -113,7 +101,9 @@ class ApplyService extends CrudService {
         );
         if (tr) continue;
         // 查看这期内,每个申请上课的教师时候超过2天(2条记录),如果超过,则不排,但是如果最后没有人了,就得硬排了
-        const r = afterList.filter(f => f.termid === termid && f.teaid === atea.teacherid);
+        const r = afterList.filter(
+          f => f.termid === termid && f.teaid === atea.teacherid
+        );
         if (r.length >= 2) {
           outTwoTimesList.push(atea);
           continue;
@@ -127,17 +117,40 @@ class ApplyService extends CrudService {
       const has_teaid = _.has(l, 'teaid');
       if (!has_teaid) {
         // 如果没有教师,就需要在outTowTimesList列表中找分最高的教师
-        const head = _.head(_.orderBy(outTwoTimesList, [ 'score' ], [ 'desc' ]));
-        if (head) {
-          l.teaid = head.teacherid;
-          l.teaname = head.teaname;
+        // const head = _.head();
+        // if (head) {
+        //   l.teaid = head.teacherid;
+        //   l.teaname = head.teaname;
+        // }
+        const list = _.orderBy(outTwoTimesList, [ 'score' ], [ 'desc' ]);
+        for (const i of list) {
+          const tr = afterList.find(
+            f => f.teaid === i.teacherid && f.day === i.date
+          );
+          if (tr) continue;
+          else {
+            l.teaid = i.teacherid;
+            l.teaname = i.teaname;
+          }
         }
       }
       afterList.push(l);
     }
     // 将afterList还原回正常的termnum;
+    const newTermnum = this.returnTermnum(afterList, termnum);
+    // 保存至计划
+    trainplan.termnum = newTermnum;
+    await trainplan.save();
+  }
+
+  /**
+   * 拍平了的课表=>termnum
+   * @param {Array} list 拍平了的课表,详情参考页面的初步课表的数据
+   * @param {Array} termnum 原termnum
+   */
+  returnTermnum(list, termnum) {
     let newTermnum = [];
-    for (const l of afterList) {
+    for (const l of list) {
       const { termid, batchid, classid, ...info } = l;
       const updata = _.pick(info, [
         'day',
@@ -146,6 +159,7 @@ class ApplyService extends CrudService {
         'teaid',
         'teaname',
         'time',
+        'status',
       ]);
       newTermnum = termnum.map(t => {
         // 找到期
@@ -180,11 +194,40 @@ class ApplyService extends CrudService {
         return t;
       });
     }
-    // 保存至计划
-    trainplan.termnum = newTermnum;
-    await trainplan.save();
+    return newTermnum;
   }
 
+  /**
+   * 将课表拍平了,从多维=>一维
+   * @param {Array} termnum 计划的termnum
+   */
+  setLessonList(termnum) {
+    const arr = [];
+    for (const t of termnum) {
+      const { batchnum, term, _id: termid } = t;
+      // 班级和课程一一匹
+      for (const b of batchnum) {
+        const { class: classes, lessons, _id: batchid } = b;
+        const claslesList = this.setList(
+          term,
+          termid,
+          batchid,
+          classes,
+          lessons
+        );
+        arr.push(...claslesList);
+      }
+    }
+    return arr;
+  }
+  /**
+   * 将课表模板和班级整理成一维数组
+   * @param {String} term 期数
+   * @param {String} termid 期id
+   * @param {String} batchid 批id
+   * @param {Array} classes 班级列表
+   * @param {Array} lessonTemplate 课表模板
+   */
   setList(term, termid, batchid, classes, lessonTemplate) {
     const arr = [];
     // 班级和课程匹配
@@ -205,6 +248,84 @@ class ApplyService extends CrudService {
     }
     return arr;
   }
+
+  async arrangeSendMsg({ planid, ids }) {
+    const trainplan = await this.trainmodel.findById(planid);
+    if (!trainplan) {
+      throw new BusinessError(ErrorCode.DATA_EXISTED, '年度计划不存在');
+    }
+    const plan = _.cloneDeep(trainplan);
+    let { termnum } = plan;
+    if (!termnum) return;
+    termnum = JSON.parse(JSON.stringify(termnum));
+    // 整理出课表
+    let arr = this.setLessonList(termnum);
+    // 过滤出需要发送的教师
+    arr = arr.filter(f => ids.find(id => f.termid === id) && f.teaid);
+    // && f.status !== '1'
+    // 整理出要发送的教师列表
+    let teaids = arr.map(i => i.teaid);
+    teaids = _.uniq(teaids);
+    // 找到教师信息
+    let teaList = await this.tmodel.find({ _id: teaids });
+    if (teaList) teaList = JSON.parse(JSON.stringify(teaList));
+    // 发送,此处是根据安排,给教师发.还有一种方案是根据教师,整理安排一起发送
+    for (const l of arr) {
+      // 教师id,期数,班级名,上课的日期,课程名
+      const { teaid, term, name, day, subname } = l;
+      const tea = teaList.find(f => f._id === teaid);
+      // 文案
+      const msg = `${_.get(tea, 'name', '')}老师您好:
+      吉林省高等学校毕业生就业指导中心-双困生培训系统提醒您:
+      ${term}期-${name.includes('班') ? name : `${name}班`}
+      ${day}(星期${this.dayList[moment(day).days()]})
+      有您的课程安排:${subname}`;
+      // 邮箱与微信都发送
+      const { openid, email } = tea;
+      if (email) {
+        this.toSendEmail('402788946@qq.com', msg, tea.name);
+      }
+      if (openid) this.toSendWxMsg('ocPqjswkUejZHq2ANriNrFFC7A3I', msg, tea.name);
+    }
+  }
+  /**
+   * 计划-教师初步课表发送邮件
+   * @param {String} email 邮件
+   * @param {String} content 内容
+   * @param {String} teaname 教师姓名
+   */
+  async toSendEmail(email, content, teaname) {
+    if (!email) {
+      console.error(`计划教师发送通知:${teaname}没有email`);
+      return;
+    }
+    const subject = '吉林省高等学校毕业生就业指导中心通知(测试)'; //
+    this.ctx.service.util.sendMail(email, subject, content);
+  }
+  /**
+   * 计划-教师初步课表发送微信推送
+   * @param {String} openid 微信公众号的openid
+   * @param {String} content 内容
+   * @param {String} teaname 教师姓名
+   */
+  async toSendWxMsg(openid, content, teaname) {
+    if (!openid) {
+      console.error(`计划教师发送微信推送:${teaname}没有openid`);
+      return;
+    }
+    // TODO or notTODO 发送微信推送记录
+    // const tourl = this.ctx.app.config.baseUrl + '/msgconfirm/?userid=' + teacherUser.uid + '&noticeid=' + nresid;
+    await this.ctx.service.weixin.sendTemplateDesign(
+      this.ctx.app.config.REVIEW_TEMPLATE_ID,
+      openid,
+      // '您有一个新的通知',
+      '测试信息推送',
+      '您有新的安排',
+      content,
+      '感谢您的使用'
+      // tourl
+    );
+  }
 }
 
 module.exports = ApplyService;