123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- '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');
- const archiver = require('archiver');
- 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 }) {
- const _model = _.capitalize(modelname);
- const data = this.ctx.model[_model].prototype.schema.obj;
- return data;
- }
- async utilMethod(data, body) {
- // 将指定计划,期数的教师状态解除确认
- let trainPlan = await this.ctx.model.Trainplan.findById('5f5adb337ceb003386c9b0d4');
- trainPlan = JSON.parse(JSON.stringify(trainPlan));
- let terms = {};
- for (const term of trainPlan.termnum) {
- if (ObjectId('5f5aed5e69b4221aedaa5005').equals(term._id)) {
- for (const batch of term.batchnum) {
- for (const c of batch.class) {
- for (const l of c.lessons) {
- l.status = '0';
- }
- }
- }
- terms = term;
- }
- }
- const i = trainPlan.termnum.findIndex(f => ObjectId('5f5aed5e69b4221aedaa5005').equals(f._id));
- trainPlan.termnum[i] = terms;
- delete trainPlan.meta;
- const r = await this.ctx.model.Trainplan.update(
- { _id: ObjectId('5f5adb337ceb003386c9b0d4') },
- { ...trainPlan }
- );
- console.log(r);
- // const output = fs.createWriteStream('E:\\exportFile\\test.zip');
- // const archive = archiver('zip', {
- // zlib: { level: 9 },
- // });
- // archive.pipe(output);
- // const res = await this.ctx.curl('http://jytz.jilinjobs.cn/files/task/20200914174650.jpg');
- // if (res && res.data) {
- // archive.append(res.data, { name: 'test.jpg', prefix: 'test/test2/test3' });
- // }
- // archive.finalize();
- }
- async teacherImport() {
- // const filepath = './teacherlist.xlsx';
- // const workbook = new Excel.Workbook();
- // await workbook.xlsx.readFile(filepath);
- // const worksheet = workbook.getWorksheet(1);
- // if (!worksheet) return;
- // let arr = [];
- // worksheet.eachRow((row, ri) => {
- // if (ri !== 1) {
- // const obj = {};
- // obj.name = row.getCell(3).value || undefined;
- // obj.department = row.getCell(4).value || undefined;
- // if (row.getCell(5).value) obj.job = row.getCell(5).value;
- // obj.phone = row.getCell(6).value || undefined;
- // obj.status = '4';
- // arr.push(obj);
- // }
- // });
- // // 检查谁生成过了, user表和teacher表
- // let ur = await this.ctx.model.User.find({ mobile: { $in: arr.map(i => i.phone) }, type: '3' });
- // let tr = await this.ctx.model.Teacher.find({ phone: { $in: arr.map(i => i.phone) } });
- // // 将有的老师过滤出去
- // if (ur) {
- // ur = JSON.parse(JSON.stringify(ur));
- // arr = arr.filter(f => !ur.find(uf => `${uf.mobile}` === `${f.phone}`));
- // }
- // if (tr) {
- // tr = JSON.parse(JSON.stringify(tr));
- // arr = arr.filter(f => !(tr.find(tf => `${tf.phone}` === `${f.phone}`)));
- // }
- // for (const tea of arr) {
- // const ctr = await this.ctx.model.Teacher.create(tea);
- // if (ctr) {
- // const obj = { name: tea.name, mobile: tea.phone, type: '3', uid: ctr._id };
- // const cur = await this.ctx.model.User.create(obj);
- // }
- // }
- // const user = await this.ctx.model.User.find({ passwd: { $exists: false } });
- // console.log(user.length);
- // for (const u of user) {
- // u.passwd = { secret: '12345678' };
- // u.save();
- // }
- }
- async toExcel(dataList, meta, fn = '导出结果') {
- console.log(meta);
- // 导出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}`;
- let path = `${rootPath}${rooturl}`;
- if (!path) {
- throw new BusinessError(ErrorCode.BUSINESS, '服务端没有设置存储路径');
- }
- if (process.env.NODE_ENV === 'development') path = 'E:\\exportFile\\';
- 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}`;
- let path = `${rootPath}${rooturl}`;
- // 如果不存在文件夹,就创建
- if (process.env.NODE_ENV === 'development') path = 'E:\\exportFile\\';
- if (!fs.existsSync(path)) {
- fs.mkdirSync(path);
- }
- const num = new Date().getTime();
- const buffer = await Packer.toBuffer(doc);
- fs.writeFileSync(`${path}${fn}-${num}.docx`, buffer);
- // Packer.toBuffer(doc).then(buffer => {
- // fs.writeFileSync(`${path}${fn}-${num}.docx`, buffer);
- // });
- return `/files${rooturl}${fn}-${num}.docx`;
- }
- /**
- * 将选择的文件导出到zip压缩包中,提供下载
- * @param {*} fileList 需要导入到zip中的列表,格式有2中: [{url:""}]或[String]
- * @param {*} fn 文件名,默认为 "导出结果"
- */
- async toZip(fileList, fn = '导出结果') {
- if (!_.isArray(fileList)) {
- throw new BusinessError(ErrorCode.DATA_INVALID, '需要压缩的文件数据格式错误');
- }
- fn = `${fn}.zip`;
- // zip文件夹创建
- const { app } = this;
- const rootPath = `${app.config.cdn.repos_root_path}`;
- const zipPath = `${app.config.cdn.repos_root_url_zip}`;
- let path = `${rootPath}${zipPath}`;
- if (process.env.NODE_ENV === 'development') path = 'E:\\exportFile\\';
- if (!fs.existsSync(path)) {
- fs.mkdirSync(path);
- }
- // 文件请求后将数据整理到这里
- const resetFileList = [];
- for (const file of fileList) {
- let uri = '';
- let filename = '';
- let prefixs;
- if (_.isString(file)) {
- uri = file;
- const arr = file.split('/');
- const last = _.last(arr);
- if (last) filename = last;
- } else if (_.isObject(file)) {
- const { uri: furi, url: furl, name, prefix } = file;
- if (furi) uri = furi;
- else if (furl) uri = furl;
- if (name) filename = name;
- else {
- const arr = uri.split('/');
- const last = _.last(arr);
- if (last) filename = last;
- }
- if (prefix) prefixs = prefix;
- }
- const obj = {};
- if (uri) obj.uri = uri;
- if (filename)obj.filename = filename;
- if (prefixs) obj.prefix = prefixs;
- resetFileList.push(obj);
- }
- // 导出
- const output = fs.createWriteStream(`${path}${fn}`);
- const archive = archiver('zip', {
- zlib: { level: 9 },
- });
- archive.pipe(output);
- // 请求文件,追加进压缩包
- for (const file of resetFileList) {
- const { uri, filename, prefix } = file;
- const res = await this.ctx.curl(`http://127.0.0.1${uri}`);
- if (res && res.data) {
- const options = {};
- if (filename)options.name = filename;
- if (prefix) options.prefix = prefix;
- if (filename) { archive.append(res.data, options); }
- }
- }
- await archive.finalize();
- return `/files${zipPath}${fn}`;
- }
- }
- module.exports = UtilService;
|