'use strict'; const assert = require('assert'); const _ = require('lodash'); const { ObjectId } = require('mongoose').Types; const moment = require('moment'); const { CrudService } = require('naf-framework-mongoose/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; class LessonService extends CrudService { constructor(ctx) { super(ctx, 'lesson'); this.model = this.ctx.model.Lesson; this.tmodel = this.ctx.model.Trainplan; this.clamodel = this.ctx.model.Class; this.lmodel = this.ctx.model.Lessonmode; this.teamodel = this.ctx.model.Teacher; this.stumodel = this.ctx.model.Student; this.schmodel = this.ctx.model.School; this.headteamodel = this.ctx.model.Headteacher; this.umodel = this.ctx.model.User; this.nmodel = this.ctx.model.Notice; } // 自动排课私有方法 async autolesson({ id }) { // 首先将课程表清空 const res = await this.tmodel.findById(id); if (!res) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '全年计划信息不存在'); } const terms = res.termnum; const _lessonmode = await this.lmodel.find(); // 循环取得所有期 for (const elm of terms) { // 根据期id清空课程表 await this.model.deleteMany({ termid: elm.id }); // 清空成功后,循环取得当前期下所有批次信息 const batchs = elm.batchnum; for (const batch of batchs) { // 取得当前批次开始结束日期,并根据日期取得所有天数 const sedays = await this.getAllDays(batch.startdate, batch.enddate); // 根据批次取得当前批次下所有班级 const _classs = await this.clamodel.find({ planid: id, termid: elm.id, batchid: batch.id, }); // 循环班级 const teachids = []; for (const cla of _classs) { // 取得课程模板信息 let lessonmode_ = _.find(_lessonmode, { type: cla.type }); if (!lessonmode_) { lessonmode_ = _lessonmode[0]; if (!lessonmode_) { throw new BusinessError( ErrorCode.DATA_NOT_EXIST, '课程模板信息不存在' ); } } // 取得模板内容并转化成json const lessons_ = JSON.parse(lessonmode_.lessons); // 记录天数 let i = 1; // 循环天数 const newlesson = []; for (const day of sedays) { // 循环课程模板,将模板信息排入班级课程表中 for (const lessm of lessons_) { // 循环插入模板信息 if (lessm['day' + i] !== '--') { let _subid = ''; if (lessm['day' + i + 'type'] === '课程') { _subid = lessm['day' + i + 'subid']; } else { _subid = ''; } let allday = 0; if (i === 6) { // 判断是否有外市的学生有的时候 将其设置为半天 const ishalfday = await this.ishalfday(cla.id); if (ishalfday) { allday = 1; } } const data = { subid: _subid, subname: lessm['day' + i], date: day, time: lessm.time, day: allday, }; // 将教师按照分数的综合成绩排序,上报时间,安排教师. const teacher_ = await this.autoteacher(_subid, teachids); if (teacher_) { data.teaid = teacher_.id; data.teaname = teacher_.name; teachids.push(teacher_.id); } newlesson.push(data); } } i = i + 1; } const newdata = { termid: elm.id, batchid: batch.id, classid: cla.id, lessons: newlesson, }; // 将课程信息填入课程表 await this.model.create(newdata); } } } } // 自动排教师,按照分数的综合成绩排序,上报时间,安排教师 async autoteacher(subid, teachids) { // 按照上报时间取得所有老师,进行正序排列 const teachers = await this.teamodel .find({ subid, status: '4' }) .sort({ zlscore: '-1', msscore: '-1', xsscore: '-1' }); for (const teaid of teachids) { _.remove(teachers, item => item.id === teaid); } let teacher = {}; if (teachers.length > 0) { teacher = teachers[0]; } return teacher; } // 判断是否为半天 async ishalfday(classid) { // 通过班级id取得所有学生 const students = await this.stumodel.find({ classid }); let res = false; for (const stu of students) { const sch = await this.schmodel.findOne({ code: stu.schid }); if (sch && sch.hascar === '0') { res = true; break; } } return res; } // 取得日期间所有日期 async getAllDays(begin_date, end_date) { const errArr = [], resultArr = [], dateReg = /^[2]\d{3}-[01]\d-[0123]\d$/; if ( typeof begin_date !== 'string' || begin_date === '' || !dateReg.test(begin_date) ) { return errArr; } if ( typeof end_date !== 'string' || end_date === '' || !dateReg.test(end_date) ) { return errArr; } try { const beginTimestamp = Date.parse(new Date(begin_date)), endTimestamp = Date.parse(new Date(end_date)); // 开始日期小于结束日期 if (beginTimestamp > endTimestamp) { return errArr; } // 开始日期等于结束日期 if (beginTimestamp === endTimestamp) { resultArr.push(begin_date); return resultArr; } let tempTimestamp = beginTimestamp, tempDate = begin_date; // 新增日期是否和结束日期相等, 相等跳出循环 while (tempTimestamp !== endTimestamp) { resultArr.push(tempDate); // 增加一天 tempDate = moment(tempTimestamp).add(1, 'd').format('YYYY-MM-DD'); // 将增加时间变为时间戳 tempTimestamp = Date.parse(new Date(tempDate)); } // 将最后一天放入数组 resultArr.push(end_date); return resultArr; } catch (err) { return errArr; } } // 根据计划id、教师id查询所有班级信息 async classbyteaid({ planid, teaid }) { // 取得传入的计划id与教师id // 根据计划id取得所有期 const plan = await this.tmodel.findById(planid); if (!plan) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '全年计划信息不存在'); } const terms = await plan.termnum; // 循环取得所有期信息 const data = []; for (const term of terms) { // 根据期id与教师id查出课程班级信息 const lessons = await this.model.find({ termid: term.id, 'lessons.teaid': teaid, }); const batchs = await term.batchnum; for (const elm of lessons) { const newdata = {}; const batch = await batchs.id(elm.batchid); newdata.planid = planid; newdata.title = plan.title; newdata.termid = elm.termid; newdata.term = term.term; newdata.batchid = elm.batchid; newdata.batch = batch.batch; newdata.classid = elm.classid; if (elm.classid) { const cla = await this.clamodel.findById(elm.classid); if (cla) { newdata.classname = cla.name; } } const _lessons = elm.lessons.filter(item => item.teaid === teaid); newdata.lessons = _lessons; data.push(newdata); } } return data; } // 根据计划id、教师id查询所有班级信息 async teaclass({ planid, teaid }) { // 取得传入的计划id与教师id // 根据计划id取得所有期 const plan = await this.tmodel.findById(planid); if (!plan) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '全年计划信息不存在'); } const terms = await plan.termnum; // 循环取得所有期信息 const data = []; for (const term of terms) { // 根据期id与教师id查出课程班级信息 const lessons = await this.model.find({ termid: term.id, 'lessons.teaid': teaid, }); for (const elm of lessons) { if (elm.classid) { const cla = await this.ctx.service.class.fetch({ id: elm.classid }); data.push(cla); } } } return data; } async uplessones(data) { for (const _data of data) { await this.model.findByIdAndUpdate(_data.id, _data); } } /** * 修改课表的状态,并发送信息 * @param {Array} ids 要修改的课表 */ async check({ ids }) { // 1,修改课表状态; TODO 2,拿到所有的班级,获取所有人员;3,然后发送信息 const list = await this.model.find({ _id: { $in: ids } }); const res = await this.model.updateMany({ _id: { $in: ids } }, { status: '1' }); // 循环课表 for (const lessonInfo of list) { // 获取期数 const { termid, classid, lessons } = lessonInfo; const planRes = await this.tmodel.findOne({ termnum: { $elemMatch: { _id: termid } } }); if (!planRes) continue; const term = planRes.termnum.find(f => ObjectId(termid).equals(f._id)); if (!term) continue; const { term: termnum, batchnum } = term; let start; let end; if (batchnum) { const { startdate, enddate } = batchnum; if (startdate) start = startdate; if (enddate) end = enddate; } const classInfo = await this.clamodel.findById(classid); // 先查找信息,如果有,不需要创建,修改创建信息,获取数据 const content = `欢迎参加由吉林省高等学校毕业生就业指导中心举办的"双困生培训会"第${termnum}期-${classInfo.name}${classInfo.name.includes('班') ? '' : '班'}${start ? `(${start}至${end})` : ''}`; let is_update = false; let nres = await this.nmodel.findOne({ planyearid: planRes.planyearid, planid: planRes._id, termid, classid, noticeid: 'system', type: '4', }); console.log(nres); let alreadyList = []; if (nres) { const { notified } = nres; alreadyList = notified.filter(i => i.status === '1'); is_update = true; } if (!is_update) { nres = await this.nmodel.create({ planyearid: planRes.planyearid, planid: planRes._id, termid, classid, noticeid: 'system', type: '4', content, }); } const { headteacherid, lyteacherid } = classInfo; const headteacher = await this.headteamodel.findById(headteacherid); if (headteacher) { const r = await this.toSendMsg(headteacher, 'headteacher', termnum, nres._id, content, alreadyList); if (r && !is_update) nres.notified.push(r); else if (r && is_update) { const dr = nres.notified.find(f => f.notifiedid === r.notifiedid); if (!dr) nres.notified.push(r); } } // 礼仪教师和班主任不是一个人时查礼仪教师是班主任还是任课教师,然后发消息 if (lyteacherid !== headteacherid) { let lyTeacher = await this.headteamodel.findById(lyteacherid); if (lyTeacher) { const r = await this.toSendMsg(lyTeacher, 'headteacher', termnum, nres._id, content, alreadyList); if (r && !is_update) nres.notified.push(r); else if (r && is_update) { const dr = nres.notified.find(f => f.notifiedid === r.notifiedid); if (!dr) nres.notified.push(r); } } else { lyTeacher = await this.teamodel.findById(lyteacherid); if (lyTeacher) { const r = await this.toSendMsg(lyTeacher, 'teacher', termnum, nres._id, content, alreadyList); if (r && !is_update) nres.notified.push(r); else if (r && is_update) { const dr = nres.notified.find(f => f.notifiedid === r.notifiedid); if (!dr) nres.notified.push(r); } } } } // 获取所有任课教师ids const teacherList = _.compact(_.uniq(lessons.map(i => i.teaid))); if (teacherList) { for (const tea of teacherList) { const teacher = await this.teamodel.findById(tea); if (!teacher) continue; const r = await this.toSendMsg(teacher, 'teacher', termnum, nres._id, content, alreadyList); if (r && !is_update) nres.notified.push(r); else if (r && is_update) { const dr = nres.notified.find(f => f.notifiedid === r.notifiedid); if (!dr) nres.notified.push(r); } } } nres.save(); } } async toSendMsg(teacherInfo, type, term, nresid, content, alreadyList) { const r = alreadyList.find(f => ObjectId(f.notifiedid).equals(teacherInfo._id)); if (r) return; let person = null; if (teacherInfo) { let email; if (type === 'headteacher') { const { qq } = teacherInfo; if (qq) email = `${qq}@qq.com`; } else { email = teacherInfo.email; } // 发邮件 if (email) { // console.error(`${teacherInfo.name}-email:${email}`); const subject = '吉林省高等学校毕业生就业指导中心通知'; const text = teacherInfo.name + `${content},请您尽快登陆双困生培训系统查看您的安排,系统邮件,请勿回复!`; // this.ctx.service.util.sendMail(email, subject, text); } // 获取openid,推送 const teacherUser = await this.umodel.findOne({ uid: teacherInfo._id }); if (teacherUser) { const { openid } = teacherUser; if (openid) { const tourl = this.ctx.app.config.baseUrl + '/msgconfirm/?userid=' + teacherUser.uid + '¬iceid=' + nresid; // TODO 推送 await this.ctx.service.weixin.sendTemplateDesign( this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知,请点击信息,确认您已收到信息!(若已确认,则无需理会)', '您有新的安排', content, '感谢您的使用', tourl ); person = { notifiedid: teacherUser.uid, username: teacherUser.name }; } } } return person; } } module.exports = LessonService;