'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 TaskService extends CrudService { constructor(ctx) { super(ctx, 'task'); this.model = this.ctx.model.Task; } async export({ range, subid }) { console.log(range, subid); // 找到学生 // 修改条件,termid变成数组了,需要一个一个查出来 const { planid, termid, batchid, classid } = range; const queryObject = {}; if (planid) queryObject.planid = planid; if (batchid) queryObject.batchid = batchid; if (classid) queryObject.classid = classid; let studentList = []; for (const t of termid) { queryObject.termid = t; const { data: stuList } = await this.ctx.service.student.query(queryObject); studentList.push(...stuList); } if (studentList.length <= 0) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到任何学生信息'); } studentList = JSON.parse(JSON.stringify(studentList)); // 找到作业 const taskList = await this.getTaskInfo(range, subid); // prefix 最少 科目名称/人 可能出现 选择到期:期/班/科目/人; 选择到批:期/批/班/科目/人; 选择到班:科目/人 ;选择计划:期/批/班/科目/人 // 找到应该是哪种模式的文件夹,同时可以获得压缩包的名称 const { fn, prefix: pn } = await this.getFnDir(range); // 循环作业,之后匹配所需要的信息 const arr = []; for (const task of taskList) { const { lessonname, studentid, picurl } = task; const stu = studentList.find(f => f._id === studentid); if (!stu) continue; const { name: studentname, termname, batchname, classname } = stu; let picarr = []; if (_.isString(picurl)) { picarr = [ picurl ]; } else { picarr = picurl; } for (const uri of picarr) { const obj = { uri }; const keys = Object.keys(pn); let prefix = `${lessonname}/${studentname}/`; if (keys.includes('class')) { prefix = `${classname}/${prefix}`; } if (keys.includes('batchid')) { prefix = `${batchname}/${prefix}`; } if (keys.includes('term')) { prefix = `${termname}/${prefix}`; } obj.prefix = prefix; arr.push(obj); } } return await this.ctx.service.util.toZip(arr, fn); } async getTaskInfo(range, subid) { const { planid, termid, batchid, classid } = range; let lessonList = []; // 找到指定范围的课表 if (classid) { lessonList = await this.ctx.model.Lesson.find({ classid }); } else if (batchid) { lessonList = await this.ctx.model.Lesson.find({ batchid }); } else if (termid) { lessonList = await this.ctx.model.Lesson.find({ termid: { $in: termid } }); } else if (planid) { const trainPlan = await this.ctx.model.Trainplan.findById(planid); if (!trainPlan) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到年度计划信息'); } let { termnum } = trainPlan; if (!termnum) { throw new BusinessError( ErrorCode.DATA_NOT_EXIST, '未找到年度计划下的期信息' ); } termnum = JSON.parse(JSON.stringify(termnum)); const termids = termnum.map(i => i._id); lessonList = await this.ctx.model.Lesson.find({ termid: { $in: termids } }); } lessonList = JSON.parse(JSON.stringify(lessonList)); // 不需要其他属性,只要课表安排 lessonList = lessonList.map(i => i.lessons); lessonList = lessonList.flat(); // 过滤出有subid且 !==''的课程 lessonList = lessonList.filter(f => f.subid && f.subid !== ''); // 如果指定某科,就把这科过滤出来 if (subid) lessonList = lessonList.filter(f => f.subid === subid); // 找作业 const lessonids = lessonList.map(i => i._id); let taskList = await this.ctx.model.Uploadtask.find({ lessonid: { $in: lessonids }, }); taskList = JSON.parse(JSON.stringify(taskList)); const arr = []; for (const task of taskList) { const r = arr.find(f => f.studentid === task.studentid && f.lessonid === task.lessonid); if (!r) arr.push(task); } return JSON.parse(JSON.stringify(arr)); } async getFnDir(range) { const { planid, termid, batchid, classid } = range; let fn = '作业'; const prefix = { class: true }; // 只有班级 if (classid) { const cla = await this.ctx.service.class.fetch({ id: classid }); if (cla) { const { name, term } = cla; if (name) fn = `${name.includes('班') ? name : `${name}班`}${fn}`; if (term) fn = `第${term}期${fn}`; } } else if (batchid) { const tid = _.head(termid); const obj = await this.toGetFn(tid, batchid); if (obj) { const { term, batch } = obj; if (batch) fn = `第${batch}批${fn}`; if (term) fn = `第${term}期${fn}`; } prefix.term = true; prefix.batch = true; } else if (termid) { if (termid.length === 1) { const obj = await this.toGetFn(_.head(termid)); if (obj) { const { term } = obj; if (term) fn = `第${term}期${fn}`; } } else { let tStr = ''; for (let i = 0; i < termid.length; i++) { const tid = termid[i]; const obj = await this.toGetFn(tid); if (obj) { const { term } = obj; if (term) { if (i === 0) { tStr += `${term}期`; } else { tStr += `,${term}期`; } } } } fn = `${tStr}${fn}`; } prefix.term = true; } else { const trainPlan = await this.ctx.model.Trainplan.findById(planid); if (trainPlan) { const { title } = trainPlan; if (title) fn = `${title}${fn}`; } prefix.term = true; prefix.batch = true; } return { fn, prefix }; } async toGetFn(termid, batchid) { const trainPlan = await this.ctx.model.Trainplan.findOne({ 'termnum._id': ObjectId(termid) }); if (!trainPlan) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到年度计划信息'); const { termnum } = trainPlan; if (!termnum) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到年度计划的期信息'); const obj = {}; if (termid) { const term = termnum.id(termid); if (term) obj.term = term.term; if (batchid) { const { batchnum } = term; const batch = batchnum.id(batchid); if (batch) obj.batch = batch.batch; } } return obj; } } module.exports = TaskService;