cheny 4 yıl önce
ebeveyn
işleme
e6a566312d
4 değiştirilmiş dosya ile 146 ekleme ve 6 silme
  1. 5 2
      app/controller/trainplan.js
  2. 1 0
      app/router.js
  3. 120 4
      app/service/trainplan.js
  4. 20 0
      app/utils/utils.js

+ 5 - 2
app/controller/trainplan.js

@@ -7,13 +7,16 @@ const { CrudController } = require('naf-framework-mongoose/lib/controller');
 
 // 培训计划管理
 class TrainplanController extends Controller {
-
   constructor(ctx) {
     super(ctx);
     this.service = this.ctx.service.trainplan;
   }
 
-
+  // 导出exportExcel
+  async exportExcel() {
+    const data = await this.service.exportExcel(this.ctx.request.body);
+    this.ctx.ok({ data });
+  }
 }
 
 module.exports = CrudController(TrainplanController, meta);

+ 1 - 0
app/router.js

@@ -86,6 +86,7 @@ module.exports = app => {
   // 培训计划表设置路由
   router.resources('trainplan', '/api/train/trainplan', controller.trainplan); // index、create、show、destroy
   router.post('trainplan', '/api/train/trainplan/update/:id', controller.trainplan.update);
+  router.post('/api/train/trainplan/exportExcel', controller.trainplan.exportExcel);// 导出
 
   // 培训计划年度批次表设置路由
   router.resources('trainplanyear', '/api/train/trainplanyear', controller.trainplanyear); // index、create、show、destroy

+ 120 - 4
app/service/trainplan.js

@@ -1,12 +1,10 @@
 'use strict';
 
 
-const assert = require('assert');
 const _ = require('lodash');
-const { ObjectId } = require('mongoose').Types;
 const { CrudService } = require('naf-framework-mongoose/lib/service');
-const { BusinessError, ErrorCode } = require('naf-core').Error;
-
+const XLSX = require('xlsx');
+const utils = require('../utils/utils.js');
 class TrainplanService extends CrudService {
   constructor(ctx) {
     super(ctx, 'trainplan');
@@ -15,6 +13,7 @@ class TrainplanService extends CrudService {
     this.umodel = this.ctx.model.User;
     this.smodel = this.ctx.model.School;
     this.tmodel = this.ctx.model.Teacher;
+    this.stumodel = this.ctx.model.Student;
   }
 
   //   async create(data) {
@@ -201,6 +200,123 @@ class TrainplanService extends CrudService {
   //     }
   //   }
   // }
+  async exportExcel({ trainplanIds }) {
+    const nowDate = new Date().getTime();
+    const path =
+            'D:\\wwwroot\\service\\service-file\\upload\\train\\' +
+            nowDate +
+            '.xlsx';
+    const respath =
+            'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
+
+    for (let i = 0; i < trainplanIds.length; i++) {
+      // 批次期次都在这里面
+      const trainplan = await this.model.findOne({ _id: trainplanIds[i] });
+      // 这个计划下所有的学生
+      const studentList = await this.stumodel.find({ planid: trainplanIds[i] });
+      // 计划名称
+      const trainplandName = trainplan.title;
+      // 在计划中找到这个学生在哪期以及哪期下的哪批次
+      for (const student of studentList) {
+        student.trainplandName = trainplandName;
+        // 期次
+        const term = trainplan.termnum.filter(term => {
+          return term.id === student.termid;
+        });
+        if (term.length > 0) { student.termName = term[0].term; }
+        // 批次
+        if (term.length !== 0) {
+          const batch = term[0].batchnum.filter(batch => {
+            return batch.id === student.batchid;
+          });
+          if (batch.length > 0) {
+            student.batchName = JSON.parse(JSON.stringify(batch[0])).name;
+          }
+        }
+
+        student.is_fine = utils.getIsNot(student.is_fine);
+      }
+      const _headers = [
+        { key: 'trainplandName', title: '计划标题' },
+        { key: 'termName', title: '期次' },
+        { key: 'batchName', title: '批次' },
+        { key: 'school_name', title: '学校' },
+        { key: 'faculty', title: '院系' },
+        { key: 'major', title: '专业' },
+        { key: 'name', title: '姓名' },
+        { key: 'id_number', title: '身份证号' },
+        { key: 'phone', title: '手机号' },
+        { key: 'gender', title: '性别' },
+        { key: 'nation', title: '民族' },
+        { key: 'edua_level', title: '学历层次' },
+        { key: 'edua_system', title: '学制' },
+        { key: 'entry_year', title: '入学年份' },
+        { key: 'finish_year', title: '毕业年份' },
+        { key: 'school_job', title: '在校职务' },
+        { key: 'qq', title: 'QQ号' },
+        { key: 'email', title: '邮箱' },
+        { key: 'openid', title: '微信openid' },
+        { key: 'family_place', title: '家庭位置' },
+        { key: 'family_is_hard', title: '是否困难' },
+        { key: 'have_grant', title: ' 是否获得过助学金' },
+        { key: 'job', title: '职务' },
+        { key: 'bedroom', title: '寝室号' },
+        { key: 'is_fine', title: '是否优秀' },
+        // { key: 'selfscore', title: '个人分' },
+        // { key: 'score', title: '总分' },
+        // { key: 'diy', title: '自定义' },
+      ];
+
+      // 需要打出的列表
+      const _data = studentList;
+      const headers = _headers
+        .map(({ title }) => title)
+        .map((v, i) =>
+          Object.assign({}, { v, position: String.fromCharCode(65 + i) + 1 })
+        )
+        .reduce(
+          (prev, next) =>
+            Object.assign({}, prev, { [next.position]: { v: next.v } }),
+          {}
+        );
+
+      const data = _data
+        .map((v, i) =>
+          _headers.map(({ key }, j) =>
+            Object.assign(
+              {},
+              { v: v[key], position: String.fromCharCode(65 + j) + (i + 2) }
+            )
+          )
+        )
+        .reduce((prev, next) => prev.concat(next))
+        .reduce(
+          (prev, next) =>
+            Object.assign({}, prev, { [next.position]: { v: next.v } }),
+          {}
+        );
+
+      // 合并 headers 和 data
+      const output = Object.assign({}, headers, data);
+
+      // 获取所有单元格的位置
+      const outputPos = Object.keys(output);
+
+      // 计算出范围
+      const ref = outputPos[0] + ':' + outputPos[outputPos.length - 1];
+
+      // 构建 workbook 对象
+      const wb = {
+        SheetNames: [ 'sheet1' ],
+        Sheets: {
+          sheet1: Object.assign({}, output, { '!ref': ref }),
+        },
+      };
+      // 导出 Excel
+      XLSX.writeFile(wb, path);
+    }
+    return respath;
+  }
 
 }
 module.exports = TrainplanService;

+ 20 - 0
app/utils/utils.js

@@ -0,0 +1,20 @@
+'use strict';
+
+
+exports.getIsNot = function(value) {
+  let isNot = '';
+  // eslint-disable-next-line default-case
+  switch (value) {
+    case '0':
+      isNot = '否';
+      break;
+    case '1':
+      isNot = '是';
+      break;
+    case '2':
+      isNot = '无资格';
+      break;
+  }
+
+  return isNot;
+};