瀏覽代碼

企业调查导出

lrf 3 年之前
父節點
當前提交
8807969eea
共有 7 個文件被更改,包括 157 次插入70 次删除
  1. 68 65
      app/controller/.investigation.js
  2. 1 0
      app/router/investigation.js
  3. 76 1
      app/service/investigation.js
  4. 4 1
      config/config.default.js
  5. 4 1
      config/config.prod.js
  6. 4 2
      package.json
  7. 二進制
      template/template.docx

+ 68 - 65
app/controller/.investigation.js

@@ -1,94 +1,97 @@
 module.exports = {
   create: {
     requestBody: [
-      "name",
-      "address",
-      "postal",
-      "web_site",
-      "register_type",
-      "field",
-      "register_time",
-      "funds",
-      "register_address",
-      "brief",
-      "legal_person",
-      "person_number",
-      "bk_number",
-      "research_number",
-      "advanced_number",
-      "contact",
-      "contact_tel",
-      "email",
-      "qq",
-      "products",
-      "requirement",
-      "techol_name",
-      "urgent",
-      "cooperation",
-      "budget",
+      'name',
+      'address',
+      'postal',
+      'web_site',
+      'register_type',
+      'field',
+      'register_time',
+      'funds',
+      'register_address',
+      'brief',
+      'legal_person',
+      'person_number',
+      'bk_number',
+      'research_number',
+      'advanced_number',
+      'contact',
+      'contact_tel',
+      'email',
+      'qq',
+      'products',
+      'requirement',
+      'techol_name',
+      'urgent',
+      'cooperation',
+      'budget',
     ],
   },
   destroy: {
-    params: ["!id"],
-    service: "delete",
+    params: ['!id'],
+    service: 'delete',
   },
   update: {
-    params: ["!id"],
+    params: ['!id'],
     requestBody: [
-      "name",
-      "address",
-      "postal",
-      "web_site",
-      "register_type",
-      "field",
-      "register_time",
-      "funds",
-      "register_address",
-      "brief",
-      "legal_person",
-      "person_number",
-      "bk_number",
-      "research_number",
-      "advanced_number",
-      "contact",
-      "contact_tel",
-      "email",
-      "qq",
-      "products",
-      "requirement",
-      "techol_name",
-      "urgent",
-      "cooperation",
-      "budget",
+      'name',
+      'address',
+      'postal',
+      'web_site',
+      'register_type',
+      'field',
+      'register_time',
+      'funds',
+      'register_address',
+      'brief',
+      'legal_person',
+      'person_number',
+      'bk_number',
+      'research_number',
+      'advanced_number',
+      'contact',
+      'contact_tel',
+      'email',
+      'qq',
+      'products',
+      'requirement',
+      'techol_name',
+      'urgent',
+      'cooperation',
+      'budget',
     ],
   },
   show: {
     parameters: {
-      params: ["!id"],
+      params: ['!id'],
     },
-    service: "fetch",
+    service: 'fetch',
   },
   index: {
     parameters: {
       query: {
-        "meta.createdAt@start": "meta.createdAt@start",
-        "meta.createdAt@end": "meta.createdAt@end",
-        name: "name",
-        field: "field",
-        register_time: "register_time",
-        register_type: "register_type",
-        contact_tel: "contact_tel",
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
+        name: 'name',
+        field: 'field',
+        register_time: 'register_time',
+        register_type: 'register_type',
+        contact_tel: 'contact_tel',
       },
       // options: {
       //   "meta.state": 0 // 默认条件
       // },
     },
-    service: "query",
+    service: 'query',
     options: {
-      query: ["skip", "limit"],
-      sort: ["meta.createdAt"],
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
       desc: true,
       count: true,
     },
   },
+  export: {
+    requestBody:[]
+  },
 };

+ 1 - 0
app/router/investigation.js

@@ -5,6 +5,7 @@ module.exports = app => {
   const { router, controller } = app;
   const profix = '/api/question/';
   const target = 'investigation';
+  router.post(target, `${profix}${target}/export`, controller[target].export);
   router.resources(target, `${profix}${target}`, controller[target]); // index、create、show、destroy
   router.post(target, `${profix}${target}/update/:id`, controller[target].update);
 };

+ 76 - 1
app/service/investigation.js

@@ -3,12 +3,20 @@ 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 = {}) {
@@ -23,6 +31,73 @@ class InvestigationService extends CrudService {
     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;

+ 4 - 1
config/config.default.js

@@ -47,7 +47,10 @@ module.exports = appInfo => {
     appid: 'wx6db5d25b3e7cfc14', // 微信公众号APPID
     baseUrl: 'http://wx.cc-lotus.info', // 微信网关地址
   };
-
+  config.export = {
+    root_path: 'S:\\workspace\\exportFile',
+    domain: 'http://broadcast.waityou24.cn',
+  };
 
   return {
     ...config,

+ 4 - 1
config/config.prod.js

@@ -13,6 +13,9 @@ module.exports = () => {
       useCreateIndex: true,
     },
   };
-  
+  config.export = {
+    root_path: 'D:\\free\\workspace\\server\\service-file\\upload',
+    domain: 'http://127.0.0.1',
+  };
   return config;
 };

+ 4 - 2
package.json

@@ -7,13 +7,15 @@
     "framework": "naf-framework-mongoose"
   },
   "dependencies": {
+    "docxtemplater": "^3.26.4",
     "egg": "^2.15.1",
-    "egg-scripts": "^2.11.0",
     "egg-naf-amqp": "0.0.13",
     "egg-redis": "^2.4.0",
+    "egg-scripts": "^2.11.0",
     "lodash": "^4.17.15",
     "moment": "^2.24.0",
-    "naf-framework-mongoose": "^0.6.11"
+    "naf-framework-mongoose": "^0.6.11",
+    "pizzip": "^3.1.1"
   },
   "devDependencies": {
     "autod": "^3.0.1",

二進制
template/template.docx