|
@@ -10,6 +10,8 @@ const { CrudService } = require('naf-framework-mongoose/lib/service');
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const moment = require('moment');
|
|
const moment = require('moment');
|
|
const nodemailer = require('nodemailer');
|
|
const nodemailer = require('nodemailer');
|
|
|
|
+const { template } = require('lodash');
|
|
|
|
+const docx = require('docx');
|
|
|
|
|
|
class UtilService extends CrudService {
|
|
class UtilService extends CrudService {
|
|
async updatedate() {
|
|
async updatedate() {
|
|
@@ -70,21 +72,56 @@ class UtilService extends CrudService {
|
|
}
|
|
}
|
|
|
|
|
|
async findmodel({ modelname }) {
|
|
async findmodel({ modelname }) {
|
|
- const _model = _.capitalize(modelname);
|
|
|
|
- const data = this.ctx.model[_model].prototype.schema.obj;
|
|
|
|
- return data;
|
|
|
|
- }
|
|
|
|
- async utilMethod(data, body) {
|
|
|
|
- console.log(data, body);
|
|
|
|
- // const res = await this.ctx.model.Student.updateMany({ ...data, classid: { $exists: true } }, { classid: null });
|
|
|
|
- const { code, ids, bedroomid } = body;
|
|
|
|
- for (const id of ids) {
|
|
|
|
- const r = await this.ctx.model.Student.findById(id);
|
|
|
|
- r.bedroom = code;
|
|
|
|
- r.bedroomid = bedroomid;
|
|
|
|
- await r.save();
|
|
|
|
- // await this.ctx.model.Student.findByIdAndUpdate(id, { bedroom: code, bedroomid });
|
|
|
|
- }
|
|
|
|
|
|
+ // TODO找到这个班级
|
|
|
|
+ // const tclass = { name: '1', term: '', batch: '' };
|
|
|
|
+ // 首先用名字找能不能对上,名字能对上直接把班级信息复制过来
|
|
|
|
+ // 名字对不上就根据当前班级的期找下本期的所有班,然后找到和他同批次的班级,查下它是第几位,按照这个位置去把模板的同位置班级信息复制过来
|
|
|
|
+
|
|
|
|
+ // 获取所有年度的期计划
|
|
|
|
+
|
|
|
|
+ // 处理学生入学年份超过4位的情况
|
|
|
|
+ // const list = await this.ctx.model.Student.find({ $where: 'this.entry_year.length>4' });
|
|
|
|
+ // const m = /^\w{4}/;
|
|
|
|
+ // for (const stu of list) {
|
|
|
|
+ // const { entry_year } = stu;
|
|
|
|
+ // const r = entry_year.match(m);
|
|
|
|
+ // if (r) {
|
|
|
|
+ // stu.entry_year = r[0];
|
|
|
|
+ // stu.save();
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // 处理学生毕业年份超过4位的情况
|
|
|
|
+ // const list = await this.ctx.model.Student.find({ $where: 'this.finish_year.length>4' });
|
|
|
|
+ // const m = /^\w{4}/;
|
|
|
|
+ // for (const stu of list) {
|
|
|
|
+ // const { finish_year } = stu;
|
|
|
|
+ // const r = finish_year.match(m);
|
|
|
|
+ // if (r) {
|
|
|
|
+ // stu.finish_year = r[0];
|
|
|
|
+ // stu.save();
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // 处理学生专业字段(major)带'专业'二字
|
|
|
|
+ // const stuList = await this.ctx.model.Student.find({ major: /专业/ });
|
|
|
|
+ // const m = /(\S+)(专业$)/;
|
|
|
|
+ // for (const stu of stuList) {
|
|
|
|
+ // const { name, major } = stu;
|
|
|
|
+ // const r = major.match(m);
|
|
|
|
+ // let nm;
|
|
|
|
+ // if (r) nm = r[1];
|
|
|
|
+ // stu.major = nm;
|
|
|
|
+ // stu.save();
|
|
|
|
+ // }
|
|
|
|
+ // 处理教师分数错误的初始化
|
|
|
|
+ // // 所有教师的分数都复制到beforescore上,xsscore需要重新计算
|
|
|
|
+ // const list = await this.ctx.model.Teacher.find();
|
|
|
|
+ // console.log(list.length);
|
|
|
|
+ // for (const tea of list) {
|
|
|
|
+ // if (tea.xsscore) {
|
|
|
|
+ // tea.beforescore = tea.xsscore;
|
|
|
|
+ // await tea.save();
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
}
|
|
}
|
|
|
|
|
|
async toExcel(dataList, meta, fn = '导出结果') {
|
|
async toExcel(dataList, meta, fn = '导出结果') {
|
|
@@ -113,6 +150,68 @@ class UtilService extends CrudService {
|
|
await workbook.xlsx.writeFile(filepath);
|
|
await workbook.xlsx.writeFile(filepath);
|
|
return `/files/excel/${filename}`;
|
|
return `/files/excel/${filename}`;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 导出docx
|
|
|
|
+ * @param {Array} data 数据[{title,content([]),author}]
|
|
|
|
+ * @param {String} fn 文件名
|
|
|
|
+ */
|
|
|
|
+ async toDocx(data, fn = '培训心得') {
|
|
|
|
+ const { Document, Packer, Paragraph, TextRun, HeadingLevel, AlignmentType } = docx;
|
|
|
|
+ const doc = new Document();
|
|
|
|
+ const children = [];
|
|
|
|
+ // 整理数据
|
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
|
+ const obj = data[i];
|
|
|
|
+ const { title, content, author } = obj;
|
|
|
|
+ const c = [];
|
|
|
|
+ if (title) {
|
|
|
|
+ const tit = new Paragraph({
|
|
|
|
+ children: [ new TextRun({ text: title, bold: true }) ],
|
|
|
|
+ heading: HeadingLevel.TITLE,
|
|
|
|
+ alignment: AlignmentType.CENTER,
|
|
|
|
+ });
|
|
|
|
+ c.push(tit);
|
|
|
|
+ }
|
|
|
|
+ if (author) {
|
|
|
|
+ const auth = new Paragraph({
|
|
|
|
+ children: [ new TextRun({ color: '#000000', text: author }) ],
|
|
|
|
+ heading: HeadingLevel.HEADING_2,
|
|
|
|
+ alignment: AlignmentType.RIGHT,
|
|
|
|
+ });
|
|
|
|
+ c.push(auth);
|
|
|
|
+ }
|
|
|
|
+ if (content && _.isArray(content) && content.length > 0) {
|
|
|
|
+ for (const cont of content) {
|
|
|
|
+ const p = new Paragraph({
|
|
|
|
+ children: [ new TextRun({ text: cont, bold: true }) ],
|
|
|
|
+ });
|
|
|
|
+ c.push(p);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (i !== data.length - 1) {
|
|
|
|
+ // 换页
|
|
|
|
+ const last = new Paragraph({
|
|
|
|
+ pageBreakBefore: true,
|
|
|
|
+ });
|
|
|
|
+ c.push(last);
|
|
|
|
+ }
|
|
|
|
+ if (c.length > 0) children.push(...c);
|
|
|
|
+ }
|
|
|
|
+ doc.addSection({
|
|
|
|
+ properties: {},
|
|
|
|
+ children,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const { app } = this;
|
|
|
|
+ const rootPath = `${app.config.cdn.repos_root_path}`;
|
|
|
|
+ const rooturl = `${app.config.cdn.repos_root_url_experience}`;
|
|
|
|
+ const path = `${rootPath}${rooturl}`;
|
|
|
|
+ Packer.toBuffer(doc).then(buffer => {
|
|
|
|
+ fs.writeFileSync(`${path}${fn}.docx`, buffer);
|
|
|
|
+ });
|
|
|
|
+ return `/files${rooturl}${fn}.docx`;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
module.exports = UtilService;
|
|
module.exports = UtilService;
|