|
@@ -1,6 +1,5 @@
|
|
|
'use strict';
|
|
|
|
|
|
-
|
|
|
const assert = require('assert');
|
|
|
const _ = require('lodash');
|
|
|
const { ObjectId } = require('mongoose').Types;
|
|
@@ -22,6 +21,8 @@ class StudentService extends CrudService {
|
|
|
this.scoremodel = this.ctx.model.Score;
|
|
|
this.leavemodel = this.ctx.model.Leave;
|
|
|
this.attendmodel = this.ctx.model.Attendance;
|
|
|
+ const { baseUrl } = _.get(this.ctx.app.config, 'mission');
|
|
|
+ if (baseUrl) this.missionBase = baseUrl;
|
|
|
}
|
|
|
|
|
|
async create(data) {
|
|
@@ -69,54 +70,56 @@ class StudentService extends CrudService {
|
|
|
}
|
|
|
|
|
|
// 查询
|
|
|
- async query({ skip, limit, ...info }) {
|
|
|
- const total = await this.model.count(info);
|
|
|
- let res = await this.model
|
|
|
- .find(info)
|
|
|
- .skip(Number(skip))
|
|
|
- .limit(Number(limit));
|
|
|
- res = JSON.parse(JSON.stringify(res));
|
|
|
- let termList = res.map(i => i.termid);
|
|
|
- termList = _.compact(_.uniq(termList));
|
|
|
- termList = termList.map(i => ObjectId(i));
|
|
|
- const planList = await this.tmodel.find({
|
|
|
- 'termnum._id': { $in: termList },
|
|
|
- });
|
|
|
- let classid = res.map(i => i.classid);
|
|
|
- classid = _.compact(_.uniq(classid));
|
|
|
- classid = classid.map(i => ObjectId(i));
|
|
|
- const classList = await this.clamodel.find({ _id: { $in: classid } });
|
|
|
- // 整理数据
|
|
|
- res = res.map(i => {
|
|
|
- const { planid, termid, batchid, classid } = i;
|
|
|
- // 拿出班级名称
|
|
|
- const cla = classList.find(f => ObjectId(classid).equals(f._id));
|
|
|
- if (cla) {
|
|
|
- const { name: classname } = cla;
|
|
|
- i.classname = classname;
|
|
|
+ async query({ name, ...info }, { skip = 0, limit = 0 } = {}) {
|
|
|
+ const query = { ...info };
|
|
|
+ if (name) {
|
|
|
+ query.name = { $regex: name };
|
|
|
+ }
|
|
|
+ let data = await this.model
|
|
|
+ .find(query)
|
|
|
+ .populate([
|
|
|
+ {
|
|
|
+ path: 'classid',
|
|
|
+ model: 'Class',
|
|
|
+ select: 'name',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'planid',
|
|
|
+ model: 'Trainplan',
|
|
|
+ },
|
|
|
+ ])
|
|
|
+ .skip(parseInt(skip))
|
|
|
+ .limit(parseInt(limit));
|
|
|
+ data = JSON.parse(JSON.stringify(data));
|
|
|
+ for (const stu of data) {
|
|
|
+ const { classid, planid, termid, batchid } = stu;
|
|
|
+ // 先拿学生
|
|
|
+ if (classid && _.isObject(classid)) {
|
|
|
+ const { _id, name } = classid;
|
|
|
+ if (name) stu.classname = name;
|
|
|
+ if (_id) stu.classid = _id;
|
|
|
}
|
|
|
- const plan = planList.find(f => ObjectId(planid).equals(f._id));
|
|
|
- if (plan) {
|
|
|
- const { termnum } = plan;
|
|
|
+ // 拼计划信息
|
|
|
+ if (planid && _.isObject(planid)) {
|
|
|
+ const { termnum, _id } = planid;
|
|
|
if (termnum && _.isArray(termnum)) {
|
|
|
- const termInfo = termnum.id(termid);
|
|
|
- if (termInfo) {
|
|
|
- const { term, batchnum } = termInfo;
|
|
|
- if (term) i.termname = term;
|
|
|
+ const t = termnum.find(f => f._id === termid);
|
|
|
+ if (t) {
|
|
|
+ const { batchnum, term } = t;
|
|
|
+ if (term) stu.termname = term;
|
|
|
if (batchnum && _.isArray(batchnum)) {
|
|
|
- const batchInfo = batchnum.id(batchid);
|
|
|
- if (batchInfo) {
|
|
|
- const { batch } = batchInfo;
|
|
|
- if (batch) i.batchname = batch;
|
|
|
+ const b = batchnum.find(f => f._id === batchid);
|
|
|
+ if (b) {
|
|
|
+ const { batch } = b;
|
|
|
+ if (batch) stu.batchname = batch;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ stu.planid = _id;
|
|
|
}
|
|
|
- return i;
|
|
|
- });
|
|
|
- const result = { total, data: res };
|
|
|
- return result;
|
|
|
+ }
|
|
|
+ return data;
|
|
|
}
|
|
|
|
|
|
async count({ name, ...info }) {
|
|
@@ -489,119 +492,217 @@ class StudentService extends CrudService {
|
|
|
}
|
|
|
number = 1;
|
|
|
}
|
|
|
-
|
|
|
- // 导出学生
|
|
|
- async exportStudent(body) {
|
|
|
- let { model, ...data } = body;
|
|
|
- // 整理model
|
|
|
- model = model.map(i => {
|
|
|
- const { zh, model } = i;
|
|
|
- if (zh && model) {
|
|
|
- const obj = {};
|
|
|
- obj.header = zh;
|
|
|
- if (model === 'termid') obj.key = 'termname';
|
|
|
- else if (model === 'batchid') obj.key = 'batchname';
|
|
|
- else if (model === 'classid') obj.key = 'classname';
|
|
|
- else obj.key = model;
|
|
|
- obj.width = 20;
|
|
|
- return obj;
|
|
|
+ // 建立导出学生名单的任务
|
|
|
+ async toExport(body) {
|
|
|
+ const { planid, termid, batchid, classid } = body;
|
|
|
+ const trainPlan = await this.ctx.model.Trainplan.findById(planid);
|
|
|
+ let fn = '学生名单';
|
|
|
+ if (termid && termid.length > 0) {
|
|
|
+ if (classid) {
|
|
|
+ const cla = await this.ctx.model.Class.findById(classid);
|
|
|
+ if (cla) {
|
|
|
+ const { name } = cla;
|
|
|
+ if (name) {
|
|
|
+ fn = `${name.includes('班') ? name : `${name}班`}${fn}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
- model = _.compact(model);
|
|
|
- // 请求数据
|
|
|
- // 修改条件,termid变成数组了,需要一个一个查出来
|
|
|
- const { planid, termid, batchid, classid } = data;
|
|
|
- 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.query(queryObject);
|
|
|
- studentList.push(...stuList);
|
|
|
+ if (termid.length === 1) {
|
|
|
+ const tid = _.head(termid);
|
|
|
+ const { termnum } = trainPlan;
|
|
|
+ const t = termnum.id(tid);
|
|
|
+ if (t) {
|
|
|
+ const { term, batchnum } = t;
|
|
|
+ if (batchid) {
|
|
|
+ const b = batchnum.id(batchid);
|
|
|
+ if (b) {
|
|
|
+ const { batch } = b;
|
|
|
+ if (b) fn = `第${batch}批${fn}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (term) fn = `第${term}期${fn}`;
|
|
|
+ }
|
|
|
+ } else if (termid.length > 1) {
|
|
|
+ const { termnum } = trainPlan;
|
|
|
+ let str = '第';
|
|
|
+ for (const tid of termid) {
|
|
|
+ const t = termnum.id(tid);
|
|
|
+ if (t) {
|
|
|
+ const { term } = t;
|
|
|
+ str = `${str}${term} `;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fn = `${str}期${fn}`;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const { title } = trainPlan;
|
|
|
+ fn = `${title}${fn}`;
|
|
|
}
|
|
|
- studentList = JSON.parse(JSON.stringify(studentList));
|
|
|
- let ids = studentList.map(i => i.classid);
|
|
|
- ids = _.uniq(ids);
|
|
|
- ids = _.compact(ids);
|
|
|
- ids = ids.map(i => ObjectId(i));
|
|
|
- const classList = await this.ctx.model.Class.find({ _id: { $in: ids } });
|
|
|
- for (const stu of studentList) {
|
|
|
- // 转换是否参培
|
|
|
- const { classid, isComming } = stu;
|
|
|
- if (!classid) continue;
|
|
|
- const cla = await this.ctx.service.class.fetch({ id: classid });
|
|
|
- if (!cla) continue;
|
|
|
- const { startdate } = cla;
|
|
|
- if (!startdate) continue;
|
|
|
- stu.insurance = moment(startdate).add(1, 'd').format('YYYY-MM-DD');
|
|
|
- if (isComming) {
|
|
|
- if (isComming === '0') stu.isComming = '否';
|
|
|
- if (isComming === '1') stu.isComming = '是';
|
|
|
+ const data = {
|
|
|
+ title: fn,
|
|
|
+ params: {
|
|
|
+ project: 'center',
|
|
|
+ // router: '/api/train/mission/student/export',
|
|
|
+ service: 'student',
|
|
|
+ method: 'exportStudent',
|
|
|
+ body,
|
|
|
+ },
|
|
|
+ };
|
|
|
+ if (this.missionBase) {
|
|
|
+ const url = `${this.missionBase}/api/mission`;
|
|
|
+ const res = await this.ctx.curl(url, {
|
|
|
+ method: 'post',
|
|
|
+ headers: {
|
|
|
+ 'content-type': 'application/json',
|
|
|
+ },
|
|
|
+ data,
|
|
|
+ dataType: 'json',
|
|
|
+ });
|
|
|
+ if (res.status !== 200 || res.data.errcode !== 0) {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '创建任务失败');
|
|
|
}
|
|
|
+ } else {
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '未找到任务项目设置');
|
|
|
}
|
|
|
- let fn = '学生名单';
|
|
|
- // 因为是递进下来, batchid和classid并列,并非递进
|
|
|
- if (classid) {
|
|
|
- // 文件名称: 期, 班
|
|
|
- // 班级名上面有直接拽来
|
|
|
- const cla = classList.find(f => ObjectId(classid).equals(f._id));
|
|
|
- if (cla) {
|
|
|
- const { name, termid } = cla;
|
|
|
- if (name) fn = `${name.includes('班') ? name : `${name}班`}${fn}`;
|
|
|
- if (termid) {
|
|
|
- const obj = await this.toGetFn(termid);
|
|
|
- if (obj) {
|
|
|
- const { term } = obj;
|
|
|
- fn = `第${term}期${fn}`;
|
|
|
- }
|
|
|
+ }
|
|
|
+ // 导出学生
|
|
|
+ async exportStudent(body) {
|
|
|
+ let { missionid, model, ...data } = body;
|
|
|
+ assert(missionid, '缺少任务信息,无法执行任务');
|
|
|
+ try {
|
|
|
+ // 整理model
|
|
|
+ model = model.map(i => {
|
|
|
+ const { zh, model } = i;
|
|
|
+ if (zh && model) {
|
|
|
+ const obj = {};
|
|
|
+ obj.header = zh;
|
|
|
+ if (model === 'termid') obj.key = 'termname';
|
|
|
+ else if (model === 'batchid') obj.key = 'batchname';
|
|
|
+ else if (model === 'classid') obj.key = 'classname';
|
|
|
+ else obj.key = model;
|
|
|
+ obj.width = 20;
|
|
|
+ return obj;
|
|
|
}
|
|
|
+ });
|
|
|
+ model = _.compact(model);
|
|
|
+ // 请求数据
|
|
|
+ // 修改条件,termid变成数组了,需要一个一个查出来
|
|
|
+ const { planid, termid, batchid, classid } = data;
|
|
|
+ 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 stuList = await this.query(queryObject);
|
|
|
+ studentList.push(...stuList);
|
|
|
}
|
|
|
- } 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}`;
|
|
|
+ // 获取学生,4分之1
|
|
|
+ this.ctx.service.util.updateProcess(missionid, '25');
|
|
|
+ console.log('学生导出=>25%');
|
|
|
+ studentList = JSON.parse(JSON.stringify(studentList));
|
|
|
+ let ids = studentList.map(i => i.classid);
|
|
|
+ ids = _.uniq(ids);
|
|
|
+ ids = _.compact(ids);
|
|
|
+ ids = ids.map(i => ObjectId(i));
|
|
|
+ const classList = await this.ctx.model.Class.find({
|
|
|
+ _id: { $in: ids },
|
|
|
+ });
|
|
|
+ for (const stu of studentList) {
|
|
|
+ // 转换是否参培
|
|
|
+ const { classid, isComming } = stu;
|
|
|
+ if (!classid) continue;
|
|
|
+ const cla = await this.ctx.service.class.fetch({ id: classid });
|
|
|
+ if (!cla) continue;
|
|
|
+ const { startdate } = cla;
|
|
|
+ if (!startdate) continue;
|
|
|
+ stu.insurance = moment(startdate).add(1, 'd').format('YYYY-MM-DD');
|
|
|
+ if (isComming) {
|
|
|
+ if (isComming === '0') stu.isComming = '否';
|
|
|
+ if (isComming === '1') stu.isComming = '是';
|
|
|
+ }
|
|
|
}
|
|
|
- } else if (termid) {
|
|
|
- // 文件名称: 期
|
|
|
- if (termid.length === 1) {
|
|
|
- const obj = await this.toGetFn(_.head(termid));
|
|
|
+ // 整理完数据,4分之2
|
|
|
+ this.ctx.service.util.updateProcess(missionid, '50');
|
|
|
+ console.log('学生导出=>50%');
|
|
|
+ let fn = '学生名单';
|
|
|
+ // 因为是递进下来, batchid和classid并列,并非递进
|
|
|
+ if (classid) {
|
|
|
+ // 文件名称: 期, 班
|
|
|
+ // 班级名上面有直接拽来
|
|
|
+ const cla = classList.find(f => ObjectId(classid).equals(f._id));
|
|
|
+ if (cla) {
|
|
|
+ const { name, termid } = cla;
|
|
|
+ if (name) fn = `${name.includes('班') ? name : `${name}班`}${fn}`;
|
|
|
+ if (termid) {
|
|
|
+ const obj = await this.toGetFn(termid);
|
|
|
+ if (obj) {
|
|
|
+ const { term } = obj;
|
|
|
+ fn = `第${term}期${fn}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (batchid) {
|
|
|
+ // 文件名称,期,批
|
|
|
+ const tid = _.head(termid);
|
|
|
+ const obj = await this.toGetFn(tid, batchid);
|
|
|
if (obj) {
|
|
|
- const { term } = obj;
|
|
|
+ const { term, batch } = obj;
|
|
|
+ if (batch) fn = `第${batch}批${fn}`;
|
|
|
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);
|
|
|
+ } else if (termid) {
|
|
|
+ // 文件名称: 期
|
|
|
+ if (termid.length === 1) {
|
|
|
+ const obj = await this.toGetFn(_.head(termid));
|
|
|
if (obj) {
|
|
|
const { term } = obj;
|
|
|
- if (term) {
|
|
|
- if (i === 0) {
|
|
|
- tStr += `${term}期`;
|
|
|
- } else {
|
|
|
- tStr += `,${term}期`;
|
|
|
+ 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}`;
|
|
|
+ }
|
|
|
+ } else if (planid) {
|
|
|
+ // 文件名称:该计划标题
|
|
|
+ const trainPlan = await this.ctx.model.Trainplan.findById(planid);
|
|
|
+ if (trainPlan) {
|
|
|
+ const { title } = trainPlan;
|
|
|
+ if (title) fn = `${title}${fn}`;
|
|
|
}
|
|
|
- fn = `${tStr}${fn}`;
|
|
|
}
|
|
|
- } else if (planid) {
|
|
|
- // 文件名称:该计划标题
|
|
|
- const trainPlan = await this.ctx.model.Trainplan.findById(planid);
|
|
|
- if (trainPlan) {
|
|
|
- const { title } = trainPlan;
|
|
|
- if (title) fn = `${title}${fn}`;
|
|
|
+ // 获取文件名,60%
|
|
|
+ this.ctx.service.util.updateProcess(missionid, '60');
|
|
|
+ console.log('学生导出=>60%');
|
|
|
+ const res = await this.ctx.service.util.toExcel(studentList, model, fn);
|
|
|
+ if (!res) {
|
|
|
+ console.error(
|
|
|
+ `${moment().format('YYYY-MM-DD HH:SS:mm')} ${fn} 导出失败`
|
|
|
+ );
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, `${fn}导出失败`);
|
|
|
}
|
|
|
+ this.ctx.service.util.updateProcess(missionid, '100', '2', {
|
|
|
+ uri: res,
|
|
|
+ });
|
|
|
+ console.log('学生导出=>100%');
|
|
|
+ } catch (error) {
|
|
|
+ this.ctx.service.util.updateProcess(missionid, undefined, '3');
|
|
|
}
|
|
|
- return await this.ctx.service.util.toExcel(studentList, model, fn);
|
|
|
}
|
|
|
|
|
|
async toGetFn(termid, batchid) {
|