123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- 'use strict';
- const { CrudService } = require('naf-framework-mongoose/lib/service');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const _ = require('lodash');
- const assert = require('assert');
- const fs = require('fs');
- const path = require('path');
- const PizZip = require('pizzip');
- const Docxtemplater = require('docxtemplater');
- const archiver = require('archiver');
- const moment = require('moment');
- // 企业需求
- class InvestigationService extends CrudService {
- constructor(ctx) {
- super(ctx, 'investigation');
- this.model = this.ctx.model.Investigation;
- this.root_path = _.get(this.ctx.app.config.export, 'root_path');
- this.dir = [ 'question', 'investigation' ];
- this.exportPrefix = '企业需求调查表';
- }
- async query(filter, options = {}) {
- const { filter: nf, options: no } = this.ctx.service.util.util.dealQuery(_.cloneDeep(filter), _.cloneDeep(options));
- const { skip, limit, sort, projection } = no;
- const rs = await this.model.find(nf, projection, { skip, limit, sort }).exec();
- return rs;
- }
- async count(filter) {
- const nf = this.ctx.service.util.util.dealFilter(_.cloneDeep(filter));
- const res = await this.model.countDocuments(nf).exec();
- return res;
- }
- async export() {
- // 检验数据是否存在
- const data = await this.model.find();
- if (data.length <= 0) return '没有企业需求调查的数据';
- // 检测,创建目录
- let newPath = this.root_path;
- for (const p of this.dir) {
- newPath = path.join(newPath, p);
- if (!fs.existsSync(newPath)) {
- fs.mkdirSync(newPath);
- }
- }
- // 循环处理
- // 存储文件名, 为了之后打包文件,然后把压缩包内对应的文件删除掉
- const fileArray = [];
- for (const dup of data) {
- const d = _.omit(JSON.parse(JSON.stringify(dup)), [ 'meta' ]);
- d['meta.createdAt'] = moment(_.get(dup, 'meta.createdAt')).format('YYYY-MM-DD');
- for (const key in d) {
- const e = d[key];
- if (!_.isObject(e)) continue;
- for (const okey of Object.keys(e)) {
- d[`${key}.${okey}`] = e[okey];
- }
- }
- // 获取模板
- const content = fs.readFileSync(path.resolve('./', 'template', 'template.docx'));
- const zip = new PizZip(content);
- const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
- doc.render(d);
- const buf = doc.getZip().generate({ type: 'nodebuffer' });
- const fileName = `${_.get(d, 'name', _.get(d, '_id'))}.docx`;
- fileArray.push(fileName);
- fs.writeFileSync(path.join(newPath, fileName), buf);
- }
- const zipPath = await this.buildZip(newPath, fileArray);
- return zipPath;
- }
- /**
- * 打zip包
- * @param {String} dirPath 路径
- * @param {Array} files 文件数组
- */
- async buildZip(dirPath, files) {
- const zipName = `${this.exportPrefix}-${new Date().getTime()}.zip`;
- const output = fs.createWriteStream(path.join(`${dirPath}`, zipName));
- const archive = archiver('zip', {
- zlib: { level: 9 },
- });
- archive.pipe(output);
- for (const f of files) {
- archive.file(path.join(dirPath, f), {
- name: path.basename(f),
- });
- }
- await archive.finalize();
- // 删除文件
- for (const f of files) {
- const filePath = path.join(dirPath, f);
- fs.unlinkSync(filePath);
- }
- // 拼接口返回的路径 /files/...
- const returnPath = `/files/${this.dir.join('/')}/${zipName}`;
- return returnPath;
- }
- }
- module.exports = InvestigationService;
|