3
0

2 کامیت‌ها 8132038bfd ... b238a9e448

نویسنده SHA1 پیام تاریخ
  cheny b238a9e448 Merge branch 'master' of http://git.cc-lotus.info/new_train/service-center 4 سال پیش
  cheny 9582827e70 导出计划 4 سال پیش
4فایلهای تغییر یافته به همراه343 افزوده شده و 60 حذف شده
  1. 6 0
      app/controller/trainplan.js
  2. 3 1
      app/router.js
  3. 14 17
      app/service/school.js
  4. 320 42
      app/service/trainplan.js

+ 6 - 0
app/controller/trainplan.js

@@ -17,6 +17,12 @@ class TrainplanController extends Controller {
     const data = await this.service.exportExcel(this.ctx.request.body);
     this.ctx.ok({ data });
   }
+  // 导出exportSchool学校大表
+  async exportSchool() {
+    const data = await this.service.exportSchool(this.ctx.request.body);
+    this.ctx.ok({ data });
+  }
+
   async updateclass() {
     const data = await this.service.updateclass(this.ctx.request.body);
     this.ctx.ok({ data });

+ 3 - 1
app/router.js

@@ -207,6 +207,8 @@ module.exports = app => {
     '/api/train/trainplan/exportExcel',
     controller.trainplan.exportExcel
   ); // 导出
+
+  router.post('/api/train/trainplan/exportSchool', controller.trainplan.exportSchool); // 导出学校
   router.post(
     '/api/train/trainplan/updateclass',
     controller.trainplan.updateclass
@@ -370,7 +372,7 @@ module.exports = app => {
     controller.school.update
   );
   router.post('/api/train/school/import', controller.school.stuimport); // 名单上传
-  router.post('/api/train/school/exportSchool', controller.school.exportSchool); // 导出学校
+
   // 民族表设置路由
   router.resources('nation', '/api/train/nation', controller.nation); // index、create、show、destroy
   router.post(

+ 14 - 17
app/service/school.js

@@ -311,26 +311,23 @@ class SchoolService extends CrudService {
     ];
     // 需要打出的列表
     const _data = trainplan;
-    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 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) }
-          )
+    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) =>

+ 320 - 42
app/service/trainplan.js

@@ -16,6 +16,7 @@ class TrainplanService extends CrudService {
     this.smodel = this.ctx.model.School;
     this.tmodel = this.ctx.model.Teacher;
     this.stumodel = this.ctx.model.Student;
+    this.schmodel = this.ctx.model.Schtime;
   }
 
   //   async create(data) {
@@ -76,13 +77,23 @@ class TrainplanService extends CrudService {
         const teachers = await this.tmodel.find({ status: '4' });
         for (const teacher of teachers) {
           const teacherid = teacher._id;
-          const _teacher = await this.umodel.findOne({ uid: teacherid, type: '3' });
+          const _teacher = await this.umodel.findOne({
+            uid: teacherid,
+            type: '3',
+          });
           const openid = _teacher.openid;
           const detail = trainplan.title + '已发布,请注意查收!';
           const date = await this.ctx.service.util.updatedate();
           const remark = '感谢您的使用';
           if (openid) {
-            this.ctx.service.weixin.sendTemplateMsg(this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知', detail, date, remark);
+            this.ctx.service.weixin.sendTemplateMsg(
+              this.ctx.app.config.REVIEW_TEMPLATE_ID,
+              openid,
+              '您有一个新的通知',
+              detail,
+              date,
+              remark
+            );
           }
         }
         // 查询所有学校用户
@@ -93,7 +104,14 @@ class TrainplanService extends CrudService {
           const date = await this.ctx.service.util.updatedate();
           const remark = '感谢您的使用';
           if (openid) {
-            this.ctx.service.weixin.sendTemplateMsg(this.ctx.app.config.REVIEW_TEMPLATE_ID, openid, '您有一个新的通知', detail, date, remark);
+            this.ctx.service.weixin.sendTemplateMsg(
+              this.ctx.app.config.REVIEW_TEMPLATE_ID,
+              openid,
+              '您有一个新的通知',
+              detail,
+              date,
+              remark
+            );
           }
         }
       }
@@ -110,7 +128,15 @@ class TrainplanService extends CrudService {
       for (const batch of term.batchnum) {
         const classs = await batch.class;
         for (const cla of classs) {
-          const newdata = { name: cla.name, number: cla.number, batchid: batch.id, termid: term.id, planid: res.id, type: cla.type, headteacherid: cla.headteacherid };
+          const newdata = {
+            name: cla.name,
+            number: cla.number,
+            batchid: batch.id,
+            termid: term.id,
+            planid: res.id,
+            type: cla.type,
+            headteacherid: cla.headteacherid,
+          };
           await this.clamodel.create(newdata);
         }
       }
@@ -143,7 +169,14 @@ class TrainplanService extends CrudService {
           // 取得当前批次的班级数
           const classnum = batchnum.class;
           for (const cla of classnum) {
-            const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
+            const newdata = {
+              name: cla.name,
+              number: cla.number,
+              batchid: batchnum.id,
+              termid: el.id,
+              planid: res.id,
+              type: cla.type,
+            };
             await this.clamodel.create(newdata);
           }
         }
@@ -152,7 +185,10 @@ class TrainplanService extends CrudService {
         // 保存后所有期id
         const batchid_res = _.map(el.batchnum, 'id');
         // 保存前所有期id
-        const batchid_old = _.map(trainplanold.termnum.id(el.id).batchnum, 'id');
+        const batchid_old = _.map(
+          trainplanold.termnum.id(el.id).batchnum,
+          'id'
+        );
         // 取得要删除的期id,进行班级中删除已删除期的班级
         const delbatchs = _.difference(batchid_old, batchid_res);
         // 循环删除已经删除期的所有班级
@@ -169,13 +205,26 @@ class TrainplanService extends CrudService {
             // 取得当前批次的班级数
             const classnum = batchnum.class;
             for (const cla of classnum) {
-              const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
+              const newdata = {
+                name: cla.name,
+                number: cla.number,
+                batchid: batchnum.id,
+                termid: el.id,
+                planid: res.id,
+                type: cla.type,
+              };
               await this.clamodel.create(newdata);
             }
           } else {
-            if (batchnum.class === trainplanold.termnum.id(el.id).batchnum.id(batchnum.id).class) {
+            if (
+              batchnum.class ===
+              trainplanold.termnum.id(el.id).batchnum.id(batchnum.id).class
+            ) {
               // 编辑只会针对班级人数进行修改。
-              const _class = await this.clamodel.find({ termid: el.id, batchid: batchnum.id });
+              const _class = await this.clamodel.find({
+                termid: el.id,
+                batchid: batchnum.id,
+              });
               if (_class.length !== 0) {
                 for (const ee of _class) {
                   ee.number = batchnum.number;
@@ -184,17 +233,34 @@ class TrainplanService extends CrudService {
               } else {
                 const classnum = batchnum.class;
                 for (const cla of classnum) {
-                  const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
+                  const newdata = {
+                    name: cla.name,
+                    number: cla.number,
+                    batchid: batchnum.id,
+                    termid: el.id,
+                    planid: res.id,
+                    type: cla.type,
+                  };
                   await this.clamodel.create(newdata);
                 }
               }
             } else {
               // 当班级数有更改时
               // 删除所有班级 并重新生成班级
-              await this.clamodel.deleteMany({ termid: el.id, batchid: batchnum.id });
+              await this.clamodel.deleteMany({
+                termid: el.id,
+                batchid: batchnum.id,
+              });
               const classnum = batchnum.class;
               for (const cla of classnum) {
-                const newdata = { name: cla.name, number: cla.number, batchid: batchnum.id, termid: el.id, planid: res.id, type: cla.type };
+                const newdata = {
+                  name: cla.name,
+                  number: cla.number,
+                  batchid: batchnum.id,
+                  termid: el.id,
+                  planid: res.id,
+                  type: cla.type,
+                };
                 await this.clamodel.create(newdata);
               }
             }
@@ -202,7 +268,6 @@ class TrainplanService extends CrudService {
         }
       }
     }
-
   }
 
   // // 将分好的班级重新编排名字
@@ -222,11 +287,9 @@ class TrainplanService extends CrudService {
   async exportExcel({ trainplanIds }) {
     const nowDate = new Date().getTime();
     const path =
-            'D:\\wwwroot\\service\\service-file\\upload\\train\\' +
-            nowDate +
-            '.xlsx';
+      'D:\\wwwroot\\service\\service-file\\upload\\train\\' + nowDate + '.xlsx';
     const respath =
-            'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
+      'http://free.liaoningdoupo.com:80/files/train/' + nowDate + '.xlsx';
     const wb = {
       SheetNames: [],
       Sheets: {},
@@ -246,7 +309,9 @@ class TrainplanService extends CrudService {
         const term = trainplan.termnum.filter(term => {
           return term.id === student.termid;
         });
-        if (term.length > 0) { student.termName = term[0].term; }
+        if (term.length > 0) {
+          student.termName = term[0].term;
+        }
         // 批次
         if (term.length !== 0) {
           const batch = term[0].batchnum.filter(batch => {
@@ -291,32 +356,27 @@ class TrainplanService extends CrudService {
       ];
       // 需要打出的列表
       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 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) }
-            )
+      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 } }),
-          {}
-        );
+      ).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);
@@ -336,6 +396,225 @@ class TrainplanService extends CrudService {
     return respath;
   }
 
+
+  // 导出学校大表
+  async exportSchool({ trainplanId }) {
+    // 备注
+    const remarks = [];
+    // 期数
+    let termCount = [];
+    // 班级数
+    const classCount = [];
+    // 日期
+    const studyTime = [];
+    // 合并单元格坐标
+    const colRows = [];
+    // 列起始
+    let colzb = 3;
+    // 行起始
+    const rowzb = 1;
+    // const colRow = {
+    //   s: { c: 3, r: rowzb },
+    //   e: { c: 6, r: rowzb },
+    // };
+    // colRows.push(colRow);
+    const shcoolList = [];
+
+    // 计划表
+    const trainplan = await this.model.findOne({ _id: trainplanId });
+    // 学校报名表
+    const schtime = await this.schmodel.find({ planid: trainplanId });
+    // 期次
+    const termnums = trainplan.termnum;
+    // 学校学校数据
+    // const schools = trainplan.school;
+    const schools = await this.smodel.find({});
+    // 组装学校数据
+    for (let i = 0; i < schools.length; i++) {
+      // 学校数据
+      const shcool = [];
+      // 序号
+      shcool.push(i + 1);
+      // 学校名
+      shcool.push(schools[i].name);
+      // 总人数
+      shcool.push('');
+      for (const termnum of termnums) {
+        // 批次
+        const batchnum = termnum.batchnum;
+        // 期次所占的格(期占格)
+        const qizhange = batchnum.length - 1;
+        /**
+       * 合并单元格元素(decode_range方法解析数据格式)
+       {
+          s: { //s start 开始
+            c: 1,//cols 开始列
+            r: 0 //rows 开始行
+          },
+          e: {//e end  结束
+            c: 4,//cols 结束列
+            r: 0 //rows 结束行
+          }
+        }
+       */
+        // 添加坐标
+        const colRow = {
+          s: { c: colzb, r: rowzb },
+          e: { c: colzb + qizhange, r: rowzb },
+        };
+        // colzb为上一次终止,那么起始需+1,
+        colzb = colzb + qizhange + 1;
+        colRows.push(colRow);
+        // 向其中加入空格,以备合并单元格使用
+        const qi = [];
+        qi.push(termnum.term);
+        for (let index = 0; index < qizhange; index++) {
+          qi.push('');
+        }
+        termCount = [ ...termCount, ...qi ];
+
+        // 循环
+        for (const batch of batchnum) {
+          // 把班级数与日期放入数组中
+          classCount.push(batch.class.length);
+          let startDate = batch.startdate;
+          startDate = startDate.substr(5, 2) + '.' + startDate.substr(8, 2);
+          let endDate = batch.enddate;
+          endDate = endDate.substr(5, 2) + '.' + endDate.substr(8, 2);
+          studyTime.push(startDate + '-' + endDate);
+          // 拿着batch的id去schtime表中的arrange中查remark,将结果存入remarks中即可完成备注数组
+          let remark = '';
+          for (const sch of schtime) {
+            // 计划中学校的code=上报时的code
+            if (schools[i].code === sch.schid) {
+              for (const arrange of sch.arrange) {
+                if (arrange.batchid === batch.id) {
+                  remark = arrange.remark;
+                  // 查到了退出即可因为是个数组
+                  // 总人数
+                  shcool.push(arrange.number);
+                }
+              }
+            }
+          }
+          remarks.push(remark);
+        }
+      }
+      shcoolList.push(shcool);
+    }
+    const wscols = [
+      { wpx: 50 }, // 第一列宽度设置单位px
+    ];
+    let xuhao = [ XLSX.utils.decode_range('A1:A4') ];
+    const xuexiao = [ XLSX.utils.decode_range('B1:B4') ];
+    xuhao = [ ...xuhao, ...xuexiao, ...colRows ];
+    // console.log(xuhao);
+    const data = [];
+    // 第一行
+    const row0 = [ '序号', '学校名称', '备注' ].concat(remarks);
+    data.push(row0);
+    // 第二行
+    const row1 = [ '', '', '期数' ].concat(termCount);
+    data.push(row1);
+    // 第三行
+    const row2 = [ '', '', '班级数' ].concat(classCount);
+    data.push(row2);
+    // 第四行
+    const row3 = [ '', '', '日期' ].concat(studyTime);
+    data.push(row3);
+    for (const shcoolL of shcoolList) {
+      let count = 0;
+      for (let i = 3; i < shcoolL.length; i++) {
+        count += parseInt(shcoolL[i]);
+      }
+      // 计算出总人数,开始总认识默认的是'',这里赋值
+      shcoolL[2] = count;
+      data.push(shcoolL);
+    }
+    // ...以此类推即可
+    /** 头部-行列信息*/
+    const ws = XLSX.utils.aoa_to_sheet(data);
+
+
+    // 构建 workbook 对象
+    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';
+    // 导出
+    const wb = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
+    ws['!cols'] = wscols;
+    // xuhao.push(XLSX.utils.decode_range('B1:D1')) // 测试数据 仓库1模拟数据
+    ws['!merges'] = xuhao;
+    // console.log(xuhao);
+    XLSX.writeFile(wb, path);
+    return respath;
+
+    // // 批次期次都在这里面
+    // const trainplan = await this.model.find({ _id: trainplanId });
+    // const _headers = [
+    //   { key: 'title', title: '计划标题' },
+    //   { key: 'year', title: '年度' },
+    // ];
+    // // 需要打出的列表
+    // const _data = trainplan;
+    // 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 } }),
+    // {}
+    // );
+    // console.log('--------------------headers');
+    // console.log(headers);
+    // 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 } }),
+    // {}
+    // );
+    // console.log('--------------------data');
+    // console.log(data);
+    // // 合并 headers 和 data
+    // const output = Object.assign({}, headers, data);
+    // console.log('----------output');
+    // console.log(output);
+    // // 获取所有单元格的位置
+    // const outputPos = Object.keys(output);
+    // console.log('--------------------outputPos');
+    // console.log(outputPos);
+    // // 计算出范围
+    // const ref = outputPos[0] + ':' + outputPos[outputPos.length - 1];
+    // console.log('--------------------ref');
+    // console.log(ref);
+    // // 构建 workbook 对象
+    // 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';
+    // const wb = {
+    //   SheetNames: [ 'sheet0' ],
+    //   Sheets: { sheet0: Object.assign({}, output, { '!ref': ref }) },
+    //   // 导出 Excel
+    // };
+    // console.log('----------wb');
+    // console.log(wb);
+    // XLSX.writeFile(wb, path);
+    // return respath;
+  }
   async updateclass({ trainplanid, classid, rightHeader }) {
     assert(trainplanid && classid && rightHeader, '缺少参数项');
     // 根据全年计划表id查出对应的全年计划详细信息
@@ -367,6 +646,5 @@ class TrainplanService extends CrudService {
     }
     return await trainplan.save();
   }
-
 }
 module.exports = TrainplanService;