|
@@ -1,6 +1,5 @@
|
|
|
'use strict';
|
|
|
|
|
|
-
|
|
|
const assert = require('assert');
|
|
|
const _ = require('lodash');
|
|
|
const moment = require('moment');
|
|
@@ -79,7 +78,9 @@ class QuestionnaireService extends CrudService {
|
|
|
// 建立任务
|
|
|
async toExport(body) {
|
|
|
const { range, questionnaireid } = body;
|
|
|
- const questionnaire = await this.questionnairemodel.findById(questionnaireid);
|
|
|
+ const questionnaire = await this.questionnairemodel.findById(
|
|
|
+ questionnaireid
|
|
|
+ );
|
|
|
if (!questionnaire) {
|
|
|
throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到问卷信息');
|
|
|
}
|
|
@@ -132,66 +133,60 @@ class QuestionnaireService extends CrudService {
|
|
|
return i;
|
|
|
});
|
|
|
// 获取问卷
|
|
|
- let questionnaire = await this.questionnairemodel.findById(questionnaireid);
|
|
|
+ const questionnaire = await this.questionnairemodel.findOne(
|
|
|
+ { _id: ObjectId(questionnaireid) },
|
|
|
+ 'name'
|
|
|
+ );
|
|
|
if (!questionnaire) {
|
|
|
throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到问卷信息');
|
|
|
}
|
|
|
- this.ctx.service.util.updateProcess(missionid, '25');
|
|
|
- questionnaire = JSON.parse(JSON.stringify(questionnaire));
|
|
|
+ let fn = await this.toSetFileName(questionnaire.name, range);
|
|
|
+ // this.ctx.service.util.updateProcess(missionid, '25');
|
|
|
// 修改条件,termid变成数组了,需要一个一个查出来
|
|
|
- const { planid, termid, batchid, classid } = range;
|
|
|
+ const { planid, batchid, classid } = range;
|
|
|
+ let { termid } = range;
|
|
|
const queryObject = {};
|
|
|
if (planid) queryObject.planid = planid;
|
|
|
if (batchid) queryObject.batchid = batchid;
|
|
|
if (classid) queryObject.classid = classid;
|
|
|
- const studentList = [];
|
|
|
- const questAnswerList = [];
|
|
|
+ let count = 0;
|
|
|
+ let dp;
|
|
|
+ const qkeys = Object.keys(range);
|
|
|
+ if (qkeys.length === 2 && termid.length <= 0) {
|
|
|
+ // 说明只有planid
|
|
|
+ const plan = await this.ctx.model.Trainplan.findOne({ _id: ObjectId(planid) });
|
|
|
+ if (!plan) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到指定年度计划');
|
|
|
+ termid = plan.termnum.map(i => JSON.parse(JSON.stringify(i._id)));
|
|
|
+ }
|
|
|
for (const t of termid) {
|
|
|
queryObject.termid = t;
|
|
|
- const obj = await this.toGetData(queryObject, questionnaireid);
|
|
|
- if (!obj) continue;
|
|
|
- const { studentList: stuList, questAnswerList: qaList } = obj;
|
|
|
- if (stuList) studentList.push(...stuList);
|
|
|
- if (qaList) questAnswerList.push(...qaList);
|
|
|
- }
|
|
|
- this.ctx.service.util.updateProcess(missionid, '50');
|
|
|
- // fn,根据范围+问卷 得出文件名
|
|
|
- const fn = await this.toSetFileName(questionnaire.name, range);
|
|
|
-
|
|
|
- let excelData;
|
|
|
- if (direction === 'horizontal') {
|
|
|
- excelData = this.horizontalSetData(
|
|
|
- studentList,
|
|
|
- questAnswerList,
|
|
|
+ let data = await this.toGetData(
|
|
|
+ queryObject,
|
|
|
+ questionnaireid,
|
|
|
+ direction,
|
|
|
modelList
|
|
|
);
|
|
|
- } else if (direction === 'vertical') {
|
|
|
- excelData = this.verticaSetData(
|
|
|
- studentList,
|
|
|
- questAnswerList,
|
|
|
- modelList
|
|
|
- );
|
|
|
- } else {
|
|
|
- throw new BusinessError(
|
|
|
- ErrorCode.DATA_NOT_EXIST,
|
|
|
- '未找到excel的表头排列方式'
|
|
|
- );
|
|
|
- }
|
|
|
- this.ctx.service.util.updateProcess(missionid, '75');
|
|
|
- if (excelData) {
|
|
|
- const { head, data } = excelData;
|
|
|
- const res = await this.ctx.service.util.toExcel(data, head, fn);
|
|
|
- if (!res) {
|
|
|
- console.error(
|
|
|
- `${moment().format('YYYY-MM-DD HH:SS:mm')} ${fn} 导出失败`
|
|
|
- );
|
|
|
- throw new BusinessError(ErrorCode.SERVICE_FAULT, `${fn}导出失败`);
|
|
|
+ if (!data) continue;
|
|
|
+ if (count !== 0 && direction === 'horizontal') data.shift();
|
|
|
+ if (count !== 0 && direction === 'vertical') {
|
|
|
+ data = data.map(i => {
|
|
|
+ i.shift();
|
|
|
+ return i;
|
|
|
+ });
|
|
|
}
|
|
|
- this.ctx.service.util.updateProcess(missionid, '100', '2', {
|
|
|
- uri: res,
|
|
|
- });
|
|
|
+ const {
|
|
|
+ downloadPath,
|
|
|
+ fn: newFileName,
|
|
|
+ } = await this.ctx.service.util.toAsyncExcel(data, fn, dp, direction);
|
|
|
+ dp = downloadPath;
|
|
|
+ fn = newFileName;
|
|
|
+ count++;
|
|
|
}
|
|
|
+ this.ctx.service.util.updateProcess(missionid, '100', '2', {
|
|
|
+ uri: dp,
|
|
|
+ });
|
|
|
} catch (error) {
|
|
|
+ console.log(error);
|
|
|
this.ctx.service.util.updateProcess(missionid, undefined, '3');
|
|
|
}
|
|
|
}
|
|
@@ -200,27 +195,52 @@ class QuestionnaireService extends CrudService {
|
|
|
* 获取学生与学生回答的问卷
|
|
|
* @param {Object} condition 查询学生和学生回答问卷的条件
|
|
|
* @param {String} questionnaireid 问卷id
|
|
|
+ * @param {String} direction 方向
|
|
|
+ * @param {Array} modelList 导出字段
|
|
|
*/
|
|
|
- async toGetData(condition, questionnaireid) {
|
|
|
+ async toGetData(condition, questionnaireid, direction, modelList) {
|
|
|
// 获取学生
|
|
|
let studentList = await this.ctx.service.student.query(condition);
|
|
|
if (studentList.length <= 0) {
|
|
|
- throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到任何学生信息');
|
|
|
+ this.ctx.logger.error(`${JSON.stringify(condition)}条件下,未找到任何信息`);
|
|
|
+ return;
|
|
|
+ // throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到任何学生信息');
|
|
|
}
|
|
|
studentList = JSON.parse(JSON.stringify(studentList));
|
|
|
// 再获取问卷答案
|
|
|
- let questAnswerList = await this.ctx.model.Uploadquestion.find({
|
|
|
+ const questAnswerList = await this.ctx.model.Uploadquestion.find({
|
|
|
...condition,
|
|
|
questionnaireid,
|
|
|
});
|
|
|
if (!questAnswerList) {
|
|
|
- throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到任何完成的问卷');
|
|
|
+ this.ctx.logger.error(`${JSON.stringify(condition)}&${questionnaireid}条件下,未找到任何完成的问卷`);
|
|
|
+ return;
|
|
|
}
|
|
|
- questAnswerList = JSON.parse(JSON.stringify(questAnswerList));
|
|
|
- const obj = {};
|
|
|
- if (studentList) obj.studentList = studentList;
|
|
|
- if (questAnswerList) obj.questAnswerList = questAnswerList;
|
|
|
- return obj;
|
|
|
+ let res = [];
|
|
|
+ let data = [];
|
|
|
+ if (direction === 'horizontal') {
|
|
|
+ const head = this.getHead(direction, modelList, studentList.length);
|
|
|
+ data = this.horizontalSetData(studentList, questAnswerList, modelList);
|
|
|
+ res.push(head.map(i => i.header));
|
|
|
+ for (const d of data) {
|
|
|
+ const mid = [];
|
|
|
+ for (const h of head) {
|
|
|
+ const { key } = h;
|
|
|
+ mid.push(_.get(d, key, ''));
|
|
|
+ }
|
|
|
+ res.push(mid);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (direction === 'vertical') {
|
|
|
+ data = this.verticaSetData(studentList, questAnswerList, modelList);
|
|
|
+ res = data.map(i => Object.values(i));
|
|
|
+ } else {
|
|
|
+ throw new BusinessError(
|
|
|
+ ErrorCode.DATA_NOT_EXIST,
|
|
|
+ '未找到excel的表头排列方式'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return res;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -291,7 +311,9 @@ class QuestionnaireService extends CrudService {
|
|
|
const trainPlan = await this.ctx.model.Trainplan.findOne({
|
|
|
'termnum._id': ObjectId(termid),
|
|
|
});
|
|
|
- if (!trainPlan) { throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到年度计划信息'); }
|
|
|
+ if (!trainPlan) {
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到年度计划信息');
|
|
|
+ }
|
|
|
const { termnum } = trainPlan;
|
|
|
if (!termnum) {
|
|
|
throw new BusinessError(
|
|
@@ -312,6 +334,34 @@ class QuestionnaireService extends CrudService {
|
|
|
return obj;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 取出对应方向的表头
|
|
|
+ * @param {String} type 横纵向类型
|
|
|
+ * @param {Array} modelList 导出字段
|
|
|
+ * @param {Number} studentList count的学生数量
|
|
|
+ */
|
|
|
+ getHead(type, modelList, studentList) {
|
|
|
+ let head = [];
|
|
|
+ if (type === 'horizontal') {
|
|
|
+ // 横向头
|
|
|
+ head = modelList.map(i => {
|
|
|
+ const { zh, model, _id } = i;
|
|
|
+ const headObj = { header: zh };
|
|
|
+ if (model) headObj.key = model;
|
|
|
+ else if (_id) headObj.key = _id;
|
|
|
+ headObj.width = 20;
|
|
|
+ return headObj;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 纵向头
|
|
|
+ const head = [{ key: 'c', width: 20 }];
|
|
|
+ for (let i = 1; i <= studentList.length; i++) {
|
|
|
+ head.push({ key: `c${i}`, width: 20 });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return head;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 横向组织数据
|
|
|
* @param {Array} studentList 学生列表
|
|
@@ -319,16 +369,7 @@ class QuestionnaireService extends CrudService {
|
|
|
* @param {Array} modelList 需要导出的字段
|
|
|
*/
|
|
|
horizontalSetData(studentList, questAnswerList, modelList) {
|
|
|
- // 第一步,组织excel表头
|
|
|
- const head = modelList.map(i => {
|
|
|
- const { zh, model, _id } = i;
|
|
|
- const headObj = { header: zh };
|
|
|
- if (model) headObj.key = model;
|
|
|
- else if (_id) headObj.key = _id;
|
|
|
- headObj.width = 20;
|
|
|
- return headObj;
|
|
|
- });
|
|
|
- // 第二步,组织数据需要按照modelList的顺序进行整理
|
|
|
+ // 组织数据需要按照modelList的顺序进行整理
|
|
|
const data = [];
|
|
|
for (const stu of studentList) {
|
|
|
const obj = {};
|
|
@@ -355,10 +396,10 @@ class QuestionnaireService extends CrudService {
|
|
|
}
|
|
|
data.push(obj);
|
|
|
}
|
|
|
- const obj = {};
|
|
|
- if (head) obj.head = head;
|
|
|
- if (data) obj.data = data;
|
|
|
- return obj;
|
|
|
+ // const obj = {};
|
|
|
+ // if (head) obj.head = head;
|
|
|
+ // if (data) obj.data = data;
|
|
|
+ return data;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -368,12 +409,7 @@ class QuestionnaireService extends CrudService {
|
|
|
* @param {Array} modelList 需要导出的字段
|
|
|
*/
|
|
|
verticaSetData(studentList, questAnswerList, modelList) {
|
|
|
- // 第一步,组织excel表头,纵向不需要第一行表头,开始就是数据,表头是第一列
|
|
|
- const head = [{ key: 'c', width: 20 }];
|
|
|
- for (let i = 1; i <= studentList.length; i++) {
|
|
|
- head.push({ key: `c${i}`, width: 20 });
|
|
|
- }
|
|
|
- // 第二部,整理数据
|
|
|
+ // 整理数据
|
|
|
const data = [];
|
|
|
for (const m of modelList) {
|
|
|
const { table, model, _id, zh } = m;
|
|
@@ -404,10 +440,7 @@ class QuestionnaireService extends CrudService {
|
|
|
}
|
|
|
data.push(obj);
|
|
|
}
|
|
|
- const obj = {};
|
|
|
- if (head) obj.head = head;
|
|
|
- if (data) obj.data = data;
|
|
|
- return obj;
|
|
|
+ return data;
|
|
|
}
|
|
|
}
|
|
|
|