'use strict'; const assert = require('assert'); const _ = require('lodash'); const fs = require('fs'); const Excel = require('exceljs'); const { ObjectId } = require('mongoose').Types; const { CrudService } = require('naf-framework-mongoose/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; const moment = require('moment'); const nodemailer = require('nodemailer'); const { template } = require('lodash'); const docx = require('docx'); class UtilService extends CrudService { async updatedate() { let date = new Date(); date = moment(date).format('YYYY-MM-DD HH:mm:ss'); return date; } async sendMail(email, subject, text, html) { const setting = await this.ctx.model.Setting.findOne(); let user_email = this.ctx.app.config.user_email; let auth_code = this.ctx.app.config.auth_code; if (setting) { user_email = setting.user_email; auth_code = setting.auth_code; } const transporter = nodemailer.createTransport({ host: 'smtp.exmail.qq.com', secureConnection: true, port: 465, auth: { user: user_email, // 账号 pass: auth_code, // 授权码 }, }); const mailOptions = { from: user_email, // 发送者,与上面的user一致 to: email, // 接收者,可以同时发送多个,以逗号隔开 subject, // 标题 text, // 文本 html, }; try { await transporter.sendMail(mailOptions); return true; } catch (err) { return false; } } async findone({ modelname }, data) { // 查询单条 const _model = _.capitalize(modelname); const res = await this.ctx.model[_model].findOne({ ...data }); return res; } async findbyids({ modelname }, { data }) { // 共通批量查询方法 const _model = _.capitalize(modelname); const res = []; for (const elm of data) { const result = await this.ctx.model[_model].findById(elm); res.push(result); } return res; } async findmodel({ modelname }) { // 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 = '导出结果') { // 导出excel const { app } = this; const nowDate = new Date().getTime(); const filename = `${fn}-${nowDate}.xlsx`; // 取出预设存储地址 const rootPath = `${app.config.cdn.repos_root_path}`; const rooturl = `${app.config.cdn.repos_root_url_excel}`; const path = `${rootPath}${rooturl}`; if (!path) { throw new BusinessError(ErrorCode.BUSINESS, '服务端没有设置存储路径'); } // 如果不存在文件夹,就创建 if (!fs.existsSync(path)) { fs.mkdirSync(path); } // 生成文件 const filepath = `${path}${filename}`; fs.createWriteStream(filepath); const workbook = new Excel.Workbook(); const sheet = workbook.addWorksheet('sheet'); sheet.columns = meta; sheet.addRows(dataList); await workbook.xlsx.writeFile(filepath); 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}`; const num = new Date().getTime(); Packer.toBuffer(doc).then(buffer => { fs.writeFileSync(`${path}${fn}-${num}.docx`, buffer); }); return `/files${rooturl}${fn}-${num}.docx`; } } module.exports = UtilService;