|
@@ -16,6 +16,7 @@ class TrainplanService extends CrudService {
|
|
|
this.smodel = this.ctx.model.School;
|
|
|
this.tmodel = this.ctx.model.Teacher;
|
|
|
this.stumodel = this.ctx.model.Student;
|
|
|
+ this.schmodel = this.ctx.model.Schtime;
|
|
|
}
|
|
|
|
|
|
// async create(data) {
|
|
@@ -76,13 +77,23 @@ class TrainplanService extends CrudService {
|
|
|
const teachers = await this.tmodel.find({ status: '4' });
|
|
|
for (const teacher of teachers) {
|
|
|
const teacherid = teacher._id;
|
|
|
- const _teacher = await this.umodel.findOne({ uid: teacherid, type: '3' });
|
|
|
+ const _teacher = await this.umodel.findOne({
|
|
|
+ uid: teacherid,
|
|
|
+ type: '3',
|
|
|
+ });
|
|
|
const openid = _teacher.openid;
|
|
|
const detail = trainplan.title + '已发布,请注意查收!';
|
|
|
const date = await this.ctx.service.util.updatedate();
|
|
|
const remark = '感谢您的使用';
|
|
|
if (openid) {
|
|
|
- this.ctx.service.weixin.sendTemplateMsg(this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知', detail, date, remark);
|
|
|
+ this.ctx.service.weixin.sendTemplateMsg(
|
|
|
+ this.ctx.app.config.REVIEW_TEMPLATE_ID,
|
|
|
+ openid,
|
|
|
+ '您有一个新的通知',
|
|
|
+ detail,
|
|
|
+ date,
|
|
|
+ remark
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
// 查询所有学校用户
|
|
@@ -93,7 +104,14 @@ class TrainplanService extends CrudService {
|
|
|
const date = await this.ctx.service.util.updatedate();
|
|
|
const remark = '感谢您的使用';
|
|
|
if (openid) {
|
|
|
- this.ctx.service.weixin.sendTemplateMsg(this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知', detail, date, remark);
|
|
|
+ this.ctx.service.weixin.sendTemplateMsg(
|
|
|
+ this.ctx.app.config.REVIEW_TEMPLATE_ID,
|
|
|
+ openid,
|
|
|
+ '您有一个新的通知',
|
|
|
+ detail,
|
|
|
+ date,
|
|
|
+ remark
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -110,7 +128,15 @@ class TrainplanService extends CrudService {
|
|
|
for (const batch of term.batchnum) {
|
|
|
const classs = await batch.class;
|
|
|
for (const cla of classs) {
|
|
|
- const newdata = { name: cla.name, number: cla.number, batchid: batch.id, termid: term.id, planid: res.id, type: cla.type, headteacherid: cla.headteacherid };
|
|
|
+ const newdata = {
|
|
|
+ name: cla.name,
|
|
|
+ number: cla.number,
|
|
|
+ batchid: batch.id,
|
|
|
+ termid: term.id,
|
|
|
+ planid: res.id,
|
|
|
+ type: cla.type,
|
|
|
+ headteacherid: cla.headteacherid,
|
|
|
+ };
|
|
|
await this.clamodel.create(newdata);
|
|
|
}
|
|
|
}
|
|
@@ -143,7 +169,14 @@ class TrainplanService extends CrudService {
|
|
|
// 取得当前批次的班级数
|
|
|
const classnum = batchnum.class;
|
|
|
for (const cla of classnum) {
|
|
|
- const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
|
|
|
+ const newdata = {
|
|
|
+ name: cla.name,
|
|
|
+ number: cla.number,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ termid: el.id,
|
|
|
+ planid: res.id,
|
|
|
+ type: cla.type,
|
|
|
+ };
|
|
|
await this.clamodel.create(newdata);
|
|
|
}
|
|
|
}
|
|
@@ -152,7 +185,10 @@ class TrainplanService extends CrudService {
|
|
|
// 保存后所有期id
|
|
|
const batchid_res = _.map(el.batchnum, 'id');
|
|
|
// 保存前所有期id
|
|
|
- const batchid_old = _.map(trainplanold.termnum.id(el.id).batchnum, 'id');
|
|
|
+ const batchid_old = _.map(
|
|
|
+ trainplanold.termnum.id(el.id).batchnum,
|
|
|
+ 'id'
|
|
|
+ );
|
|
|
// 取得要删除的期id,进行班级中删除已删除期的班级
|
|
|
const delbatchs = _.difference(batchid_old, batchid_res);
|
|
|
// 循环删除已经删除期的所有班级
|
|
@@ -169,13 +205,26 @@ class TrainplanService extends CrudService {
|
|
|
// 取得当前批次的班级数
|
|
|
const classnum = batchnum.class;
|
|
|
for (const cla of classnum) {
|
|
|
- const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
|
|
|
+ const newdata = {
|
|
|
+ name: cla.name,
|
|
|
+ number: cla.number,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ termid: el.id,
|
|
|
+ planid: res.id,
|
|
|
+ type: cla.type,
|
|
|
+ };
|
|
|
await this.clamodel.create(newdata);
|
|
|
}
|
|
|
} else {
|
|
|
- if (batchnum.class === trainplanold.termnum.id(el.id).batchnum.id(batchnum.id).class) {
|
|
|
+ if (
|
|
|
+ batchnum.class ===
|
|
|
+ trainplanold.termnum.id(el.id).batchnum.id(batchnum.id).class
|
|
|
+ ) {
|
|
|
// 编辑只会针对班级人数进行修改。
|
|
|
- const _class = await this.clamodel.find({ termid: el.id, batchid: batchnum.id });
|
|
|
+ const _class = await this.clamodel.find({
|
|
|
+ termid: el.id,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ });
|
|
|
if (_class.length !== 0) {
|
|
|
for (const ee of _class) {
|
|
|
ee.number = batchnum.number;
|
|
@@ -184,17 +233,34 @@ class TrainplanService extends CrudService {
|
|
|
} else {
|
|
|
const classnum = batchnum.class;
|
|
|
for (const cla of classnum) {
|
|
|
- const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
|
|
|
+ const newdata = {
|
|
|
+ name: cla.name,
|
|
|
+ number: cla.number,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ termid: el.id,
|
|
|
+ planid: res.id,
|
|
|
+ type: cla.type,
|
|
|
+ };
|
|
|
await this.clamodel.create(newdata);
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
// 当班级数有更改时
|
|
|
// 删除所有班级 并重新生成班级
|
|
|
- await this.clamodel.deleteMany({ termid: el.id, batchid: batchnum.id });
|
|
|
+ await this.clamodel.deleteMany({
|
|
|
+ termid: el.id,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ });
|
|
|
const classnum = batchnum.class;
|
|
|
for (const cla of classnum) {
|
|
|
- const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
|
|
|
+ const newdata = {
|
|
|
+ name: cla.name,
|
|
|
+ number: cla.number,
|
|
|
+ batchid: batchnum.id,
|
|
|
+ termid: el.id,
|
|
|
+ planid: res.id,
|
|
|
+ type: cla.type,
|
|
|
+ };
|
|
|
await this.clamodel.create(newdata);
|
|
|
}
|
|
|
}
|
|
@@ -202,7 +268,6 @@ class TrainplanService extends CrudService {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
// // 将分好的班级重新编排名字
|
|
@@ -222,11 +287,9 @@ class TrainplanService extends CrudService {
|
|
|
async exportExcel({ trainplanIds }) {
|
|
|
const nowDate = new Date().getTime();
|
|
|
const path =
|
|
|
- 'D:\\wwwroot\\service\\service-file\\upload\\train\\' +
|
|
|
- nowDate +
|
|
|
- '.xlsx';
|
|
|
+ 'D:\\wwwroot\\service\\service-file\\upload\\train\\' + nowDate + '.xlsx';
|
|
|
const respath =
|
|
|
- 'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
|
|
|
+ 'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
|
|
|
const wb = {
|
|
|
SheetNames: [],
|
|
|
Sheets: {},
|
|
@@ -246,7 +309,9 @@ class TrainplanService extends CrudService {
|
|
|
const term = trainplan.termnum.filter(term => {
|
|
|
return term.id === student.termid;
|
|
|
});
|
|
|
- if (term.length > 0) { student.termName = term[0].term; }
|
|
|
+ if (term.length > 0) {
|
|
|
+ student.termName = term[0].term;
|
|
|
+ }
|
|
|
// 批次
|
|
|
if (term.length !== 0) {
|
|
|
const batch = term[0].batchnum.filter(batch => {
|
|
@@ -291,32 +356,27 @@ class TrainplanService extends CrudService {
|
|
|
];
|
|
|
// 需要打出的列表
|
|
|
const _data = studentList;
|
|
|
- const headers = _headers
|
|
|
- .map(({ title }) => title)
|
|
|
- .map((v, i) =>
|
|
|
- Object.assign({}, { v, position: String.fromCharCode(65 + i) + 1 })
|
|
|
- )
|
|
|
- .reduce(
|
|
|
- (prev, next) =>
|
|
|
- Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
- {}
|
|
|
- );
|
|
|
+ const headers = _headers.map(({ title }) =>
|
|
|
+ title).map((v, i) =>
|
|
|
+ Object.assign({}, { v, position: String.fromCharCode(65 + i) + 1 })
|
|
|
+ ).reduce((prev, next) =>
|
|
|
+ Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
+ {}
|
|
|
+ );
|
|
|
|
|
|
- const data = _data
|
|
|
- .map((v, i) =>
|
|
|
- _headers.map(({ key }, j) =>
|
|
|
- Object.assign(
|
|
|
- {},
|
|
|
- { v: v[key], position: String.fromCharCode(65 + j) + (i + 2) }
|
|
|
- )
|
|
|
+ const data = _data.map((v, i) =>
|
|
|
+ _headers.map(({ key }, j) =>
|
|
|
+ Object.assign(
|
|
|
+ {},
|
|
|
+ { v: v[key], position: String.fromCharCode(65 + j) + (i + 2) }
|
|
|
)
|
|
|
)
|
|
|
- .reduce((prev, next) => prev.concat(next))
|
|
|
- .reduce(
|
|
|
- (prev, next) =>
|
|
|
- Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
- {}
|
|
|
- );
|
|
|
+ ).reduce((prev, next) =>
|
|
|
+ prev.concat(next)).reduce(
|
|
|
+ (prev, next) =>
|
|
|
+ Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
+ {}
|
|
|
+ );
|
|
|
|
|
|
// 合并 headers 和 data
|
|
|
const output = Object.assign({}, headers, data);
|
|
@@ -336,6 +396,225 @@ class TrainplanService extends CrudService {
|
|
|
return respath;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ // 导出学校大表
|
|
|
+ async exportSchool({ trainplanId }) {
|
|
|
+ // 备注
|
|
|
+ const remarks = [];
|
|
|
+ // 期数
|
|
|
+ let termCount = [];
|
|
|
+ // 班级数
|
|
|
+ const classCount = [];
|
|
|
+ // 日期
|
|
|
+ const studyTime = [];
|
|
|
+ // 合并单元格坐标
|
|
|
+ const colRows = [];
|
|
|
+ // 列起始
|
|
|
+ let colzb = 3;
|
|
|
+ // 行起始
|
|
|
+ const rowzb = 1;
|
|
|
+ // const colRow = {
|
|
|
+ // s: { c: 3, r: rowzb },
|
|
|
+ // e: { c: 6, r: rowzb },
|
|
|
+ // };
|
|
|
+ // colRows.push(colRow);
|
|
|
+ const shcoolList = [];
|
|
|
+
|
|
|
+ // 计划表
|
|
|
+ const trainplan = await this.model.findOne({ _id: trainplanId });
|
|
|
+ // 学校报名表
|
|
|
+ const schtime = await this.schmodel.find({ planid: trainplanId });
|
|
|
+ // 期次
|
|
|
+ const termnums = trainplan.termnum;
|
|
|
+ // 学校学校数据
|
|
|
+ // const schools = trainplan.school;
|
|
|
+ const schools = await this.smodel.find({});
|
|
|
+ // 组装学校数据
|
|
|
+ for (let i = 0; i < schools.length; i++) {
|
|
|
+ // 学校数据
|
|
|
+ const shcool = [];
|
|
|
+ // 序号
|
|
|
+ shcool.push(i + 1);
|
|
|
+ // 学校名
|
|
|
+ shcool.push(schools[i].name);
|
|
|
+ // 总人数
|
|
|
+ shcool.push('');
|
|
|
+ for (const termnum of termnums) {
|
|
|
+ // 批次
|
|
|
+ const batchnum = termnum.batchnum;
|
|
|
+ // 期次所占的格(期占格)
|
|
|
+ const qizhange = batchnum.length - 1;
|
|
|
+ /**
|
|
|
+ * 合并单元格元素(decode_range方法解析数据格式)
|
|
|
+ {
|
|
|
+ s: { //s start 开始
|
|
|
+ c: 1,//cols 开始列
|
|
|
+ r: 0 //rows 开始行
|
|
|
+ },
|
|
|
+ e: {//e end 结束
|
|
|
+ c: 4,//cols 结束列
|
|
|
+ r: 0 //rows 结束行
|
|
|
+ }
|
|
|
+ }
|
|
|
+ */
|
|
|
+ // 添加坐标
|
|
|
+ const colRow = {
|
|
|
+ s: { c: colzb, r: rowzb },
|
|
|
+ e: { c: colzb + qizhange, r: rowzb },
|
|
|
+ };
|
|
|
+ // colzb为上一次终止,那么起始需+1,
|
|
|
+ colzb = colzb + qizhange + 1;
|
|
|
+ colRows.push(colRow);
|
|
|
+ // 向其中加入空格,以备合并单元格使用
|
|
|
+ const qi = [];
|
|
|
+ qi.push(termnum.term);
|
|
|
+ for (let index = 0; index < qizhange; index++) {
|
|
|
+ qi.push('');
|
|
|
+ }
|
|
|
+ termCount = [ ...termCount, ...qi ];
|
|
|
+
|
|
|
+ // 循环
|
|
|
+ for (const batch of batchnum) {
|
|
|
+ // 把班级数与日期放入数组中
|
|
|
+ classCount.push(batch.class.length);
|
|
|
+ let startDate = batch.startdate;
|
|
|
+ startDate = startDate.substr(5, 2) + '.' + startDate.substr(8, 2);
|
|
|
+ let endDate = batch.enddate;
|
|
|
+ endDate = endDate.substr(5, 2) + '.' + endDate.substr(8, 2);
|
|
|
+ studyTime.push(startDate + '-' + endDate);
|
|
|
+ // 拿着batch的id去schtime表中的arrange中查remark,将结果存入remarks中即可完成备注数组
|
|
|
+ let remark = '';
|
|
|
+ for (const sch of schtime) {
|
|
|
+ // 计划中学校的code=上报时的code
|
|
|
+ if (schools[i].code === sch.schid) {
|
|
|
+ for (const arrange of sch.arrange) {
|
|
|
+ if (arrange.batchid === batch.id) {
|
|
|
+ remark = arrange.remark;
|
|
|
+ // 查到了退出即可因为是个数组
|
|
|
+ // 总人数
|
|
|
+ shcool.push(arrange.number);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ remarks.push(remark);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ shcoolList.push(shcool);
|
|
|
+ }
|
|
|
+ const wscols = [
|
|
|
+ { wpx: 50 }, // 第一列宽度设置单位px
|
|
|
+ ];
|
|
|
+ let xuhao = [ XLSX.utils.decode_range('A1:A4') ];
|
|
|
+ const xuexiao = [ XLSX.utils.decode_range('B1:B4') ];
|
|
|
+ xuhao = [ ...xuhao, ...xuexiao, ...colRows ];
|
|
|
+ // console.log(xuhao);
|
|
|
+ const data = [];
|
|
|
+ // 第一行
|
|
|
+ const row0 = [ '序号', '学校名称', '备注' ].concat(remarks);
|
|
|
+ data.push(row0);
|
|
|
+ // 第二行
|
|
|
+ const row1 = [ '', '', '期数' ].concat(termCount);
|
|
|
+ data.push(row1);
|
|
|
+ // 第三行
|
|
|
+ const row2 = [ '', '', '班级数' ].concat(classCount);
|
|
|
+ data.push(row2);
|
|
|
+ // 第四行
|
|
|
+ const row3 = [ '', '', '日期' ].concat(studyTime);
|
|
|
+ data.push(row3);
|
|
|
+ for (const shcoolL of shcoolList) {
|
|
|
+ let count = 0;
|
|
|
+ for (let i = 3; i < shcoolL.length; i++) {
|
|
|
+ count += parseInt(shcoolL[i]);
|
|
|
+ }
|
|
|
+ // 计算出总人数,开始总认识默认的是'',这里赋值
|
|
|
+ shcoolL[2] = count;
|
|
|
+ data.push(shcoolL);
|
|
|
+ }
|
|
|
+ // ...以此类推即可
|
|
|
+ /** 头部-行列信息*/
|
|
|
+ const ws = XLSX.utils.aoa_to_sheet(data);
|
|
|
+
|
|
|
+
|
|
|
+ // 构建 workbook 对象
|
|
|
+ const nowDate = new Date().getTime();
|
|
|
+ const path =
|
|
|
+ 'D:\\wwwroot\\service\\service-file\\upload\\train\\' +
|
|
|
+ nowDate +
|
|
|
+ '.xlsx';
|
|
|
+ const respath =
|
|
|
+ 'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
|
|
|
+ // 导出
|
|
|
+ const wb = XLSX.utils.book_new();
|
|
|
+ XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
|
|
|
+ ws['!cols'] = wscols;
|
|
|
+ // xuhao.push(XLSX.utils.decode_range('B1:D1')) // 测试数据 仓库1模拟数据
|
|
|
+ ws['!merges'] = xuhao;
|
|
|
+ // console.log(xuhao);
|
|
|
+ XLSX.writeFile(wb, path);
|
|
|
+ return respath;
|
|
|
+
|
|
|
+ // // 批次期次都在这里面
|
|
|
+ // const trainplan = await this.model.find({ _id: trainplanId });
|
|
|
+ // const _headers = [
|
|
|
+ // { key: 'title', title: '计划标题' },
|
|
|
+ // { key: 'year', title: '年度' },
|
|
|
+ // ];
|
|
|
+ // // 需要打出的列表
|
|
|
+ // const _data = trainplan;
|
|
|
+ // const headers = _headers.map(({ title }) =>
|
|
|
+ // title).map((v, i) =>
|
|
|
+ // Object.assign({}, { v, position: String.fromCharCode(65 + i) + 1 })
|
|
|
+ // ).reduce((prev, next) =>
|
|
|
+ // Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
+ // {}
|
|
|
+ // );
|
|
|
+ // console.log('--------------------headers');
|
|
|
+ // console.log(headers);
|
|
|
+ // const data = _data.map((v, i) =>
|
|
|
+ // _headers.map(({ key }, j) =>
|
|
|
+ // Object.assign(
|
|
|
+ // {},
|
|
|
+ // { v: v[key], position: String.fromCharCode(65 + j) + (i + 2) }
|
|
|
+ // )
|
|
|
+ // )
|
|
|
+ // ).reduce((prev, next) =>
|
|
|
+ // prev.concat(next)).reduce((prev, next) =>
|
|
|
+ // Object.assign({}, prev, { [next.position]: { v: next.v } }),
|
|
|
+ // {}
|
|
|
+ // );
|
|
|
+ // console.log('--------------------data');
|
|
|
+ // console.log(data);
|
|
|
+ // // 合并 headers 和 data
|
|
|
+ // const output = Object.assign({}, headers, data);
|
|
|
+ // console.log('----------output');
|
|
|
+ // console.log(output);
|
|
|
+ // // 获取所有单元格的位置
|
|
|
+ // const outputPos = Object.keys(output);
|
|
|
+ // console.log('--------------------outputPos');
|
|
|
+ // console.log(outputPos);
|
|
|
+ // // 计算出范围
|
|
|
+ // const ref = outputPos[0] + ':' + outputPos[outputPos.length - 1];
|
|
|
+ // console.log('--------------------ref');
|
|
|
+ // console.log(ref);
|
|
|
+ // // 构建 workbook 对象
|
|
|
+ // const nowDate = new Date().getTime();
|
|
|
+ // const path =
|
|
|
+ // 'D:\\wwwroot\\service\\service-file\\upload\\train\\' +
|
|
|
+ // nowDate +
|
|
|
+ // '.xlsx';
|
|
|
+ // const respath =
|
|
|
+ // 'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
|
|
|
+ // const wb = {
|
|
|
+ // SheetNames: [ 'sheet0' ],
|
|
|
+ // Sheets: { sheet0: Object.assign({}, output, { '!ref': ref }) },
|
|
|
+ // // 导出 Excel
|
|
|
+ // };
|
|
|
+ // console.log('----------wb');
|
|
|
+ // console.log(wb);
|
|
|
+ // XLSX.writeFile(wb, path);
|
|
|
+ // return respath;
|
|
|
+ }
|
|
|
async updateclass({ trainplanid, classid, rightHeader }) {
|
|
|
assert(trainplanid && classid && rightHeader, '缺少参数项');
|
|
|
// 根据全年计划表id查出对应的全年计划详细信息
|
|
@@ -367,6 +646,5 @@ class TrainplanService extends CrudService {
|
|
|
}
|
|
|
return await trainplan.save();
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
module.exports = TrainplanService;
|