'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; class BedroomService extends CrudService { constructor(ctx) { super(ctx, 'bedroom'); this.model = this.ctx.model.Bedroom; this.smodel = this.ctx.model.Student; this.tmodel = this.ctx.model.Trainplan; this.cmodel = this.ctx.model.Class; this.umodel = this.ctx.model.User; this.ctmodel = this.ctx.model.Classtype; this.nmodel = this.ctx.model.Notice; } // 根据班级id查找班级下所有寝室列表并查询出寝室下学生信息 async roomstu({ id }) { // 通过班级id查询学生表信息 const students = await this.smodel.find({ classid: id }); const _bedrooms = _.map(students, 'bedroom'); // 取得无重复的寝室号 const bedrooms = _.uniq(_bedrooms); console.log(bedrooms); const data = []; // 根据寝室号 取得相应的学生信息 for (const elm of bedrooms) { const stus = students.filter(item => item.bedroom === elm); const newdata = { bedroom: elm, stus }; data.push(newdata); } return data; } async ibeacon(data) { assert(data.openid, '用户信息不能为空'); // 通过openid取得学生信息 const user = await this.ctx.service.user.findByOpenid(data.openid); if (!user) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '用户不存在'); } const student = await this.smodel.findById(user.uid); if (!student) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '学生信息不存在'); } const beedroom = await this.model.findOne({ code: student.bedroom }); if (!beedroom) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '寝室信息不存在'); } return { data: { ibeacon: beedroom.ibeacon } }; } // 一键分寝 async apart(data) { const { trainplanid, termid, batchid } = data; assert(trainplanid, 'trainplanid不能为空'); assert(termid, 'termid不能为空'); assert(batchid, 'batchid不能为空'); // 根据计划id取得当前计划 const trainplan = await this.tmodel.findById(trainplanid); // 根据期id取得当前期信息 const term = trainplan.termnum.find(p => p.id === termid); // 根据批次id查询批次信息 const _batch = term.batchnum.find(p => p.id === batchid); // 查询所有寝室列表 const bedroomList = await this.model .find({ batch: _batch.batch, status: '0' }) .sort({ floor: -1 }); // 循环所有当前批次下的寝室列表进行分寝处理 const studentList = await this.getstudents(termid, batchid); console.log('stulen-->' + studentList.length); for (const bedroom of bedroomList) { console.log(bedroom.code); // 判断当前寝室号是否已有 // 根据期id查找所有当期学生列表 const _stu = _.filter(studentList, { bedroom: bedroom.code }); console.log(_stu.length); if (bedroom.number !== _stu.length) { let i = 0; let _gender = ''; for (const stud of studentList) { console.log('stu---' + stud.bedroom); if (stud.bedroom) { if (stud.bedroom === bedroom.code) { i = i + 1; } continue; } console.log('i--->' + i); if (i === 0) { if (!bedroom.gender) { stud.bedroomid = bedroom.id; stud.bedroom = bedroom.code; await stud.save(); i = i + 1; _gender = stud.gender; } else { if (bedroom.gender === stud.gender) { stud.bedroomid = bedroom.id; stud.bedroom = bedroom.code; await stud.save(); i = i + 1; _gender = stud.gender; } } } else if (i < bedroom.number) { if (_gender === stud.gender) { stud.bedroomid = bedroom.id; stud.bedroom = bedroom.code; await stud.save(); i = i + 1; } } else if (i === bedroom.number) { i = 0; break; } } } } // 取得当前批次的所有班级 const classes = await this.cmodel.find({ batchid }); const detail = '班级学生名单与寝室安排已确认,请及时查收'; const nres = await this.nmodel.create({ planyearid: trainplan.planyearid, planid: trainplanid, termid, noticeid: 'system', content: detail, type: '5', }); for (const _class of classes) { // 取得每个班级的班主任id const headteacherid = _class.headteacherid; const headteacher = await this.umodel.findOne({ uid: headteacherid, type: '1', }); if (headteacher && headteacher.openid) { const openid = headteacher.openid; const remark = '感谢您的使用'; const date = await this.ctx.service.util.updatedate(); this.ctx.service.weixin.sendTemplateMsg( this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知', detail, date, remark, _class.id ); nres.notified.push({ notifiedid: headteacher.uid, username: headteacher.name, }); } await nres.save(); } } // 取得符合条件的学生列表 async getstudents(termid, batchid) { // 根据期id查找所有当期学生列表 const cltype = await this.ctmodel.find({ bedroom: '0' }); const types = _.map(cltype, 'code'); console.log('-----types-start--'); console.log(types); console.log('-----types-end--'); const studentList = await this.smodel .find({ termid, batchid, type: { $in: types } }) .sort({ gender: -1 }); return studentList; } // 取得符合条件的学生列表 async getbedroomstudents(termid, batchid, bedroom) { // 根据期id查找所有当期学生列表 const studentList = await this.smodel.find({ termid, batchid, bedroom }); return studentList; } // 新 分配寝室查询可以的列表 async getAssignRoom({ termid }) { console.log(termid); const bedroomList = await this.model.find(); const stuList = await this.smodel.find({ termid }); const stuBedIdGroup = _.groupBy(stuList, 'bedroomid'); const keys = Object.keys(stuBedIdGroup); // 过滤出没有人的寝室 let noperson = bedroomList.filter(f => !(keys.find(k => { if (k === undefined || k === 'undefined' || k === null || k === 'null') return false; return ObjectId(k).equals(f._id); }))); noperson = JSON.parse(JSON.stringify(noperson)); const nopersonList = []; for (const i of noperson) { const n = `${i.code}(${i.number}人)`; const obj = { ...i, name: n }; nopersonList.push(obj); } const havepersonList = []; for (const key of keys) { if (key === undefined || key === 'undefined' || key === null || key === 'null') continue; // 取出分组后,以寝室id为key的学生列表 const list = stuBedIdGroup[key]; // 找到寝室obj const bedroom = bedroomList.find(f => ObjectId(key).equals(f._id)); // 找不到寝室就算了,下一个吧 if (!bedroom) continue; // 找到这个寝室人数限制 const { number } = bedroom; // 超出,等于限制人数,继续下个寝室 if (list.length >= number * 1) continue; // 这个寝室人没满,需要组织数据了 const { _id, code, floor } = bedroom; const elsenum = number * 1 - list.length; const stu = _.head(list); const { gender } = stu; let ncode = `${code}(`; if (elsenum) ncode = `${ncode} 剩余${elsenum}人`; if (gender) ncode = `${ncode} ${gender}性`; if (floor)ncode = `${ncode} ${floor}楼`; ncode = `${ncode})`; const obj = { _id, code, name: ncode }; havepersonList.push(obj); } return [ ...nopersonList, ...havepersonList ]; } // 批量修改学生寝室(新) TODO,需要添加期id,然后找这个寝室,这期同学是否占满/性别错误的问题 async updateStudent(data, body) { const { code, ids, bedroomid, termid } = body; const bedroom = await this.model.findById(bedroomid); if (!bedroom) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '不存在该寝室'); let { number, gender } = bedroom; console.log(`bedroom:gender=>${gender}`); // 找到多少人在这个寝室 const inRoom = await this.ctx.model.Student.find({ termid, bedroomid }); const ifTotal = inRoom.length * 1 + ids.length; if (ifTotal > number * 1) throw new BusinessError(ErrorCode.BUSINESS, `超出人数,该寝室人最多为${number}人`); if (!gender) { // 寝室没设置性别,从这个寝室的学生中取出性别 const stu = _.head(inRoom); gender = _.trim(_.get(stu, 'gender')); console.log(`bedroom:in room sutdent gender=>${gender}`); } const selectStuList = await this.ctx.model.Student.find({ _id: ids.map(i => ObjectId(i)) }); for (const id of ids) { const r = await this.ctx.model.Student.findById(id); // 性别查询,是否有误 const { gender: sg, name } = r; // 寝室或有已入住学生,产生的性别结果, if (!gender) { console.log('in no gender limit'); r.bedroom = code; r.bedroomid = bedroomid; await r.save(); } else { console.log(`in gender limit : gender: ${gender} / sg:${sg}`); if (sg && sg.includes(gender)) { // 有性别判断 r.bedroom = code; r.bedroomid = bedroomid; await r.save(); } else { throw new BusinessError( ErrorCode.BusinessError, `${name} 与该寝室已分配的学生性别不符!` ); } } } } } module.exports = BedroomService;