'use strict'; const assert = require('assert'); const _ = require('lodash'); const { ObjectId } = require('mongoose').Types; const { CrudService } = require('naf-framework-mongoose/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; const sd = require('silly-datetime'); class NoticeService extends CrudService { constructor(ctx) { super(ctx, 'notice'); this.model = this.ctx.model.Notice; this.umodel = this.ctx.model.User; this.stumodel = this.ctx.model.Student; this.schmodel = this.ctx.model.School; this.heamodel = this.ctx.model.Headteacher; this.teamodel = this.ctx.model.Teacher; this.lmodel = this.ctx.model.Lesson; this.clsmodel = this.ctx.model.Class; } async create(data) { const { planyearid, planid, termid, classid, noticeid, content, notified, type } = data; assert(planyearid, '年度计划id为必填项'); assert(planid, '计划id为必填项'); assert(termid, '期id为必填项'); assert(noticeid, '通知人id为必填项'); assert(content, '通知内容为必填项'); // type:0=>所有人;1=>学生;2=>教师;3=>班主任 TODO:缺少个人发信息 const res = await this.model.create({ ...data, type: '0' }); let range = 'term'; let personList = []; if (classid) range = 'class'; if (range === 'term') { if (type === '0') { const sList = await this.getRangeStudent({ termid }); const tList = await this.getRangeTeacher({ termid }); const hList = await this.getRangeClasses({ termid }); personList = [ ...sList, ...tList, ...hList ]; } else if (type === '1') personList = await this.getRangeStudent({ termid }); else if (type === '2')personList = await this.getRangeTeacher({ termid }); else if (type === '3')personList = await this.getRangeClasses({ termid }); } else if (range === 'class') { if (type === '0') { const sList = await this.getRangeStudent({ classid }); const tList = await this.getRangeTeacher({ classid }); const hList = await this.getRangeClasses({ _id: classid }); personList = [ ...sList, ...tList, ...hList ]; } else if (type === '1') personList = await this.getRangeStudent({ classid }); else if (type === '2') personList = await this.getRangeTeacher({ classid }); else if (type === '3') personList = await this.getRangeClasses({ _id: classid }); } personList = personList.map(i => i._id); // 获取所有人后发送信息 const userList = await this.umodel.find({ uid: { $in: personList } }); console.log(userList); for (const user of userList) { // 1,判断有没有openid;2有openid的发送消息,添加记录 if (!_.get(user, 'openid')) continue; const openid = _.get(user, 'openid'); const title = '您有一个新的通知'; const detail = content; const tourl = this.ctx.app.config.baseUrl + '/trainnotice/?userid=' + user.uid + '¬iceid='; // + res.id || '' await this.toSendWithUrl(title, openid, detail, tourl); // openid const notified = _.get(res, 'notified', []); notified.push({ notifiedid: user.uid, username: user.name }); res.notified = notified; } res.save(); } /** * 根据条件返回学生列表 * @param {Object} condition 查询学生的条件 */ async getRangeStudent(condition) { const res = await this.stumodel.find({ ...condition, openid: { $exists: true } }); console.log(res); return res; } /** * 根据条件返回教师列表 * @param {Object} condition 查询教师的条件 */ async getRangeTeacher(condition) { // teamodel;lmodel const lessonList = await this.lmodel.find(condition); const teacherList = _.compact(_.uniq(lessonList.map(i => i.lessons).flat().map(i => i.teaid))); const teaInfoList = await this.teamodel.find({ _id: { $in: teacherList } }); return teaInfoList; } /** * 根据条件返回班主任 不加礼仪教师列表消息了 * @param {Object} condition 查询班主任 */ async getRangeClasses({ _id, ...info }) { let resList = []; if (_id) { const cla = await this.clsmodel.findOne({ _id: ObjectId(_id) }); if (cla) resList.push(cla.headteacherid); // , cla.lyteacherid } else { const classesList = await this.clsmodel.find(info); if (classesList) { for (const cla of classesList) { resList.push(cla.headteacherid); // , cla.lyteacherid } } } resList = _.compact(_.uniq(resList)); const headteaList = await this.heamodel.find({ _id: { $in: resList } }); resList = resList.filter(f => !headteaList.find(hf => ObjectId(f).equals(hf._id))); const teaList = await this.teamodel.find({ _id: { $in: resList } }); resList = [ ...headteaList, ...teaList ]; return resList; } async look(data) { const { noticeid, userid } = data; const notice = await this.model.findById(noticeid); if (notice) { for (const elm of notice.notified) { if (elm.notifiedid === userid) { elm.status = '1'; elm.readtime = sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss'); } } await notice.save(); } } // async query({ skip, limit, ...info }) { // const total = await this.model.count(info); // const notices = await this.model.find(info).skip(Number(skip)).limit(Number(limit)); // const res = []; // for (const _notice of notices) { // const notice = _.cloneDeep(JSON.parse(JSON.stringify(_notice))); // const { noticeid, content, notified, meta, _id } = notice; // const elm = []; // for (const notified of notice.notified) { // const _notified = _.cloneDeep(JSON.parse(JSON.stringify(notified))); // const userinfo = await this.findUserInfo(_notified.notifiedid); // elm.push({ ...JSON.parse(JSON.stringify(userinfo)), ..._notified }); // } // res.push({ noticeid, content, meta, notified: elm, _id }); // } // return { data: res, total }; // } async findUserInfo(userid) { let userinfo; userinfo = await this.heamodel.findById(userid); if (!userinfo) { userinfo = await this.schmodel.findById(userid); } if (!userinfo) { userinfo = await this.teamodel.findById(userid); if (userinfo) { delete userinfo.status; } } if (!userinfo) { userinfo = await this.stumodel.findById(userid); } return userinfo; } async resend({ id }) { const res = await this.model.findById(id); if (res) { const { content, notified } = res; const useridList = notified.filter(f => f.status === '0').map(i => i.notifiedid); const userList = await this.umodel.find({ uid: { $in: useridList } }); for (const user of userList) { if (!_.get(user, 'openid')) continue; const openid = _.get(user, 'openid'); const detail = content; const tourl = this.ctx.app.config.baseUrl + '/trainnotice/?userid=' + user.uid + '¬iceid=' + res.id; await this.toSendWithUrl('您有信息需要确认', openid, detail, tourl); } } else { throw new BusinessError(ErrorCode.DATA_NOT_EXIST); } } /** *发送自定义信息 * @param {String} title 标题 * @param {String} openid user表的openid * @param {String} detail 通知内容 * @param {String} tourl 确认通知地址 */ async toSendWithUrl(title, openid, detail, tourl) { const remark = '感谢您的使用'; const date = await this.ctx.service.util.updatedate(); this.ctx.service.weixin.sendTemplateDesign(this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, `${title},请点击信息,确认您已收到信息!`, detail, date, remark, tourl); } } module.exports = NoticeService;