123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- 'use strict';
- const _ = require('lodash');
- const fs = require('fs');
- const Excel = require('exceljs');
- const { CrudService } = require('naf-framework-mongoose/lib/service');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const moment = require('moment');
- const nodemailer = require('nodemailer');
- const docx = require('docx');
- const archiver = require('archiver');
- const { ObjectId } = require('mongoose').Types;
- class UtilService extends CrudService {
- constructor(ctx) {
- super(ctx);
- this.mq = this.ctx.mq;
- }
- 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, // 授权码
- },
- });
- if (process.env.NODE_ENV === 'development') email = '402788946@qq.com';
- 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;
- const keys = Object.keys(data);
- const res = {};
- for (const k of keys) {
- const obj = data[k];
- if (_.get(obj, 'zh')) res[k] = obj;
- }
- return res;
- }
- async utilMethod(query, body) {
- const crypto = require('crypto');
- const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
- modulusLength: 2048,
- publicKeyEncoding: {
- type: 'spki',
- format: 'pem',
- },
- privateKeyEncoding: {
- type: 'pkcs8',
- format: 'pem',
- cipher: 'aes-256-cbc',
- passphrase: 'sks_secret',
- },
- });
- console.log(publicKey);
- console.log('-------------------');
- console.log(privateKey);
- // const privateKey = `-----BEGIN ENCRYPTED PRIVATE KEY-----
- // MIIJrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI+SbyJ6RzQY8CAggA
- // MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBACELvWKbd/L0zagGXmrwrKBIIJ
- // UBn774mFtXJgWi9NVh+GO5CpcqDxU2JjP+lOILG0k9EIJiwVBH++LHtJX4S9Y7MP
- // qtJQZBLSdyjh7mzMige/xTSEkF2wGactP1QE2imfcT52NoHGQVyeFBfa+ZEZixPU
- // h/6uqS8TjABU561I3A/89vHYLrZ9va1T8AZTp4NbyUaD5zYCPUG+mn9Ln9PO56Bk
- // HEUXfZa2qGU819CxC2Ju4T/KMLDXHKVbbCiDnB1vLxuO4vSd8719nwR9czfTkGKv
- // MJtk7wbFUrstmEVFBM931D6wNT/BHtYGCf2xw10CwtSjLKbB/iINqH5CUYMjA6H8
- // 4ts7nBHkmkuRa5bGZSHeCR25fLE6i/WU0mAB4gnaU3nSmInA2JF5QFKV/2+RsZBN
- // DCAU8TwjnsY4dsqwC0CjUPY3EguiuXAVZ3eQO43ERIVuK6flfY1vaK1186KAfLf9
- // 9dYMcoag8ohs22etBiFVQZMy8YTC7knndyMyP+c/ohgENzUc1lPVHj1n0kGW2Mgu
- // Gc4mLXTmifr3SM/Z5cUI97i/OZ1aYm01G2UiR2ZLLdLSwuBoqs2J1r5Xk97BqaPm
- // f93PgENfafd7Sd+RH1f635FMKM61NbZBzNMDJmKW1B4RgezLgxanJy5AqJNGfiuS
- // 9m0daXKPEhAhh+Hx5LEYXxuSVgaSAJtvOZze5yHA/kHEy5+DZ5Gv31brEVHmAphA
- // EFSdtDbf44hqGMk2LAeiahkqc+MXz+RVFAvuh24qR8NeulIszu5ExHM13ZVL1GIP
- // IqnplKnX/Xjt8j1CJOxgiHJvqcX3LAg0NDh0CbmpSJVjjL/yqxwYMBSiLgS8ViT+
- // AaGqLvuT95Oyq7IiMDngymTMT4ilWjeY+ovFWC3JxwCL8kzFVFBL680JhOlvBVft
- // e9+JbJeV3xAq482FolBRXla6Eqe1eeFVjmY8+n/UqepT8CLk7hJxzN0VCVJsx7VT
- // wlBjRobcIdaLtwJllu7Ebpc2MwLVgPJvvNHigLJVNW5SyHhleT2pJZDROgm+0itc
- // 39L8MN5Jo/q/wqO1KO+Fx17xNiMhQr7rs+9zcy8a1/D8v0zmNbpayWx8z0V6TyYJ
- // 2QhQAPuO7mnxsbzZPEnj93+2ifoojU3YOgvxQCUR4LNbreScSotJmX8ADi9rpmgp
- // VxSUSpZ9smzX2kVMPQPWCOuNzuCJIGPmwI1+2wSGgYkPW1hjVReQTevrIt6YMKxh
- // 7NuiJ9Hzi96uGAlcfPPp85wR2NUGJ+++lu6874AHa4nfwrxBqps/e/IFgbxfOXoo
- // ZS1thHfViSlPeV6+gv2OdBb6mZbMlH2UWjKuXmvYPSKBy/PA3Kl9gyYbOnpBb7Cz
- // Bt0jpx0oJtWmndzXpRRDOj/ehppSe1tbhe3D1Eg1EOn3C0IS284dQ2JzMATbdxV3
- // okrKYcIxuYvCVNjgAo+GdfC+V3A4c15HlPjYsgy8hLIZGWbfFvNIFPNw7LmxAG6w
- // UD+EAFKtijRV/vKjMraiVfaB8LQ+QLgBkgE+8JFRkFUmwzCWB2KoewHPUbk+7/a1
- // 7PQx0+sk+ghIb6lkC0EOcAFjfDiQYJttZ/ax3txR76hHNHOcMKeFp5DgwBzlvllR
- // BHKRDHflyr6CGf9gTMw83xwHp9HCpz/BleBLvoMd23FZ/BXkHlBWUusfLlUj+iNp
- // uQuM/xXNZ9JTixibCcQzC5KFJsOcnGWkoID/nT22iR4G2nqivHcbq3GM/s+Ty9zQ
- // q7Pot2cCkPOSuacyuZxrBsWmSGVibMnYEDcWs4N3Vsgw+hrk886VLDNEt7bDwy83
- // KQflDKNSwEeav6NceWywmMWP6lQQoCPQtuUxdBpJ/vanrEOU8Tg5/PNiqnqtqtN2
- // Z6g3ZNyGFaYXkzxizznrIaH81HUmC5wVHmozzH7FiLqIt2yj+IbOBD9T4KiarnQX
- // zsgR+eYbHUO7wzOvlMj0O3n1jMHK01gBe5IlGcPW/n4/mUp8qACgVipKhO45NxL8
- // u9+BcPoBNCFD23sCnjUHChGHEhfNyQutjXyFUzmIkni4M5idudgri7KDHAdt/Sid
- // 6X2/R+b/p5zK9DqqtaEeRyQutzBJsCHaup9w46ySuen+NdfbCzITvaDpOpQJua9x
- // 4R+YEE6h31tlp13whR3wKNs7nrpS9oRQo3tXKIzDSXYZM81DuSR1fJ+6H9yAfkg5
- // 4ScerEFSU+nvwzx5Gpj8AfDQHKHOAb6uGjGMp2bDhIWqqYJZS5JkcqF3CNr7C6EE
- // A8iGy/QisX2cxquT2uKjjoIVSVVQKjrV4LI3f13bHEJ5I6RBrSWNic7WAKBkjxTH
- // OPtuz2cgL5KAs/hvhMqVaEmeGvC9mW0jy3S0rFFMZapb8OFfFM2fEVNNzMvVy2Gd
- // RAZMPY4hzyqHzlLDUOF8fGa+Tly6cG0Rjvt+EsGy7w3yhR4FEUD71T2Hdh4Qlj+f
- // J1TDw6uEHFoYZQB9mRM+b7zDZX6Q7f4Yqk8Zp4bmlvdvoPtFS8ai8qosHDKZfuJe
- // 5yRQhx7GUL6se2kzcb12ZvHWdq4i9DRZ9mamcr4lnqWc1lWF/yPxow42fcGEYiSn
- // fg458CL16dV2JMrlNI67KX/oxKQbtI8Qqow9GA0xHT9APeRHDwQH9hhPE+I9nzjk
- // vXiKSk1CyQcMFJv63Jelq9v9SlM4OhbLM6BnBMCc5UqZ5y7plN+j+1y07+TVB+qE
- // 1b8WXHKkWNm1PyUkX57amLjHzvk/z7yIAWQV35ZuZe0Hq65QfNuG8T6aMTNEUEVj
- // ciuYB1KM5XhtTJvn/EyDktpCMvPF5X++uT6Pq2dbHUSVng/JHWm8qOStBnzosvHR
- // Ebmw4uSELfqrIONBid3rUNJ0HuLhm9IcSspj+kmAkumOjX8tQ/GER/3DKs7phjir
- // sCAQBf9BxnJUICP8jbr+OYXfJs6FsPNrtEZOg+78BdFQpWGgLptUWRTjHUPR3bb2
- // J2i7ADAgW2t6eh+bhJ5JyDQ0xqGRVx57mHOvAlKkaa/GNMVexTqEH4eybilsQCpY
- // jEtwj9SJMe5jD3J4hzAQUaeOfyruuZ2R2nC1C/070TRL6qXf6DNnWeXiYIOuYW36
- // ere7RirrD3vwbgu1jzsixYgGSRXLYis42brchhzw7+9Ut3vvQCMc03aO3fe+6Aji
- // WZo3nW1v3vEf3fS4fFtQF7VP1a2A0Leawv7ZxXUS2A8S
- // -----END ENCRYPTED PRIVATE KEY-----`;
- // const publicKey = `-----BEGIN PUBLIC KEY-----
- // MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzGSOl6+oYHZyHRzJYtC3
- // wlqczFs2QKHLi6bnQj1Sb6J4Kx0UkJqb2yJpyFenBTjW+W4rMM7bt9RzM4pHqjWI
- // ubTDFL8aU8R1LxOI/9HqpC9CTyZpmGjrCZoJz07sMz/RNo6e8nwpAdEN3Z8sSaGD
- // Wm+Jv8uk8NtXDksyXa9b1aAylxMCIu+yg1V+QvAqfxFW2HHQodjE1/8/QNMqPr90
- // DoCS35atn5vl6XQyHY40jk5r6it/zr7IBkuZnPJHSL3Mcvf2lZXYSg4Q2TQ9q4G5
- // zx4UsYK3oPI/bP4+KK2o+nmdHjP+YlWpgIjMOZ7bYBu90APHUaRskRAwbruBdN0v
- // UQuUvrZ+ePptXBwvqDycCwF0VVYSUKWC0rCkk+zGNiramsILRGEbkHZ0OCIW6vs1
- // aijKiUbDLVFXRjzwKFlrczt0DszEZDvBbVU6aaia1fvHoMTa9Qh48IL7czncgwc+
- // 7n8IxyiE69PAB/Y54AoNbANsAjbHJKL5POE3g4BfJfvzGStTGHT08tdMwfyWlKa4
- // V1f9/W1PiPvr018oTyEpjYuitA1AsslJWce2PysVQc5w4EVJHMSz9feqNYv8eFSD
- // rEXSHLXwtK0TK8asdX13zi2klGe6zpkejAuLVq+PUbMV6RzTLue5qlOp/pwGuVFM
- // Z9vYX8dtRkmfeDitSjRTpEkCAwEAAQ==
- // -----END PUBLIC KEY-----`;
- const data = { code: '1', org: '2', type: '中心管理员' };
- const enc = crypto.publicEncrypt(publicKey, Buffer.from(JSON.stringify(data)));
- const str = enc.toString('base64');
- console.log(str);
- const sb = Buffer.from(str, 'base64');
- const decpub = crypto.privateDecrypt(
- {
- key: privateKey,
- passphrase: 'sks_secret',
- },
- sb
- );
- console.log(`decpub:${decpub.toString()}`);
- // for (const trainPlan of allTranPlan) {
- // const { termnum = [] } = trainPlan;
- // const termids = termnum.map(f => ObjectId(f._id).toString());
- // // 查出该期所有的申请
- // const termApplys = await applyModel.find({ termid: termids }).lean();
- // const needDeletes = termApplys.filter(f => !(allSubject.find(s => s._id === f.subid) && allTeacher.find(t => t._id === f.teacherid)));
- // const deleteIds = needDeletes.map(i => i._id);
- // console.log(deleteIds.length);
- // // await applyModel.deleteMany({ _id: deleteIds });
- // }
- // // // 重置班级
- // // 找到要删除的学生
- // const res = await this.ctx.model.Student.find({ school_name: '吉林职业技术学院', planid: '60769b703cead37068645fb2', termid: { $ne: '60779c0b2ec7ac704ce301ab' } });
- // // const test = res.map(f => {
- // // return { name: f.name, openid: f.openid, id: f._id };
- // // });
- // const ids = res.map(i => i._id);
- // await this.ctx.model.User.deleteMany({ uid: ids });
- // await this.ctx.model.Student.deleteMany({ school_name: '吉林职业技术学院', planid: '60769b703cead37068645fb2', termid: { $ne: '60779c0b2ec7ac704ce301ab' } });
- // const ids = res.map(i => i.openid);
- // // console.log(ids);
- //
- // console.log(userRes.length);
- // const { planid, termid, batchid, classid } = query;
- // const filters = {};
- // if (classid) filters.classid = classid;
- // else if (batchid)filters.batchid = batchid;
- // else if (termid)filters.termid = termid;
- // else if (planid)filters.planid = planid;
- // else throw new BusinessError(ErrorCode.BADPARAM, '需要重置范围');
- // await this.ctx.model.Student.updateMany(filters, { classid: undefined });
- // // 重置班级结束
- }
- async getQueryOptions({ skip, limit, sort, desc } = {}) {
- if (sort && _.isString(sort)) {
- sort = { [sort]: desc ? -1 : 1 };
- } else if (sort && _.isArray(sort)) {
- sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
- }
- return { skip, limit, sort };
- }
- /**
- * 更新进度,状态 不存在/完成以外(不是2的值)的数值, 不添加参数,只更新进度
- * @param {String} missionid 任务id
- * @param {String} progress 进度(人为划分)
- * @param {String} status 状态
- * @param {Object} params 参数
- */
- async updateProcess(missionid, progress, status, params) {
- try {
- if (!missionid) return;
- const { baseUrl } = _.get(this.ctx.app.config, 'mission');
- let url = `${baseUrl}`;
- let data;
- if (!baseUrl) return;
- if (!status || status !== '2') {
- url = `${url}/api/mission/progress`;
- data = { id: missionid, progress };
- } else if (status === '3') {
- url = `${url}/api/mission/update/${missionid}`;
- data = { status };
- } else {
- url = `${url}/api/mission/update/${missionid}`;
- data = { progress: '100', params, status };
- }
- await this.ctx.curl(url, {
- method: 'post',
- headers: {
- 'content-type': 'application/json',
- },
- data,
- dataType: 'json',
- });
- } catch (error) {
- console.error(`任务更新进度报错,missionid:${missionid}\n`);
- }
- }
- 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 } });
- // for (const u of user) {
- // u.passwd = { secret: '12345678' };
- // u.save();
- // }
- }
- /**
- * 导出excel
- * @param {Array} dataList 数据集合
- * @param {Array} meta 表头(可以没有)
- * @param {String} fn 文件名
- * @param {Array} opera 单元格操作
- */
- async toExcel(dataList, meta, fn = '导出结果', opera) {
- // 导出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 (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');
- if (meta) sheet.columns = meta;
- sheet.addRows(dataList);
- if (_.isArray(opera)) {
- for (const o of opera) {
- const { startRow, startCol, endRow, endCol } = o;
- sheet.mergeCells(startRow, startCol, endRow, endCol);
- }
- }
- // 垂直居中
- const length = dataList.length;
- const alignment = { vertical: 'middle', horizontal: 'center' };
- for (let i = 1; i <= length; i++) {
- sheet.getRow(i).alignment = alignment;
- }
- await workbook.xlsx.writeFile(filepath);
- return `/files/excel/${filename}`;
- }
- /**
- * 创建/重复写入excel
- * @param {Array} dataList 数据
- * @param {String} fn 文件名, 第一次进入时,只是单纯的名,第二次开始,有后缀与时间戳
- * @param {String} downloadPath 下载文件路径
- * @param {String} type 方向,没有默认横向
- */
- async toAsyncExcel(dataList, fn = '导出结果', downloadPath, type) {
- const { app } = this;
- const workbook = new Excel.Workbook();
- let sheet;
- // 取出预设存储地址
- const rootPath = `${app.config.cdn.repos_root_path}`;
- const rooturl = `${app.config.cdn.repos_root_url_excel}`;
- let path = `${rootPath}${rooturl}`;
- let filepath = '';
- if (!path) {
- throw new BusinessError(ErrorCode.BUSINESS, '服务端没有设置存储路径');
- }
- if (process.env.NODE_ENV === 'development') path = 'E:\\exportFile\\excel\\';
- if (!fs.existsSync(path)) {
- // 如果不存在文件夹,就创建
- fs.mkdirSync(path);
- }
- if (!downloadPath) {
- // 第一次进入,文件还未生成
- const nowDate = new Date().getTime();
- fn = `${fn}-${nowDate}.xlsx`;
- sheet = workbook.addWorksheet('sheet');
- } else {
- let domain = 'http://127.0.0.1';
- if (process.env.NODE_ENV === 'development') domain = `${domain}:8000`;
- const file = await this.ctx.curl(`${domain}${downloadPath}`);
- if (!(file && file.data)) {
- throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找导出的excel');
- }
- // 读取文件
- await workbook.xlsx.load(file.data);
- sheet = workbook.getWorksheet('sheet');
- }
- if (!type || type === 'horizontal') sheet.addRows(dataList);
- else if (type === 'vertical') {
- for (let i = 1; i <= dataList.length; i++) {
- const element = dataList[i - 1];
- const rows = sheet.getRow(i);
- if (rows.values.length <= 0) rows.values = element;
- else rows.values = rows.values.concat(element);
- rows.commit();
- }
- }
- filepath = `${path}${fn}`;
- await workbook.xlsx.writeFile(filepath);
- return { downloadPath: `/files/excel/${fn}`, fn };
- }
- /**
- * 导出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}`;
- // 如果不存在文件夹,就创建
- // 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;
|