lrf402788946 4 éve
szülő
commit
48f5c17fc8
1 módosított fájl, 78 hozzáadás és 44 törlés
  1. 78 44
      app/service/count.js

+ 78 - 44
app/service/count.js

@@ -20,59 +20,93 @@ class CountService extends CrudService {
 
   // 查询
   async countstudent() {
+    // levelexit:退出人数 √
+    // levelqj:请假人数 √
+    // notrainstu:上传名单,但是未培训人数 student表中的数据不稳,后加的可能没有了.被人绑定更换也可能没有了.所以 这个数字用 student.total - user(type=4&&openid) 的结果 √
+    // schstu:上传名单人数 该年度计划下,的student.total √
+    // trainstu:已参加培训人数 user(type==4&&openid).total √
+    // planstu:年度计划人数(重算) 根据年度计划学校的分配计算 √
+    // schs:[{schname 学校名称,schnum 学校人数}] 学校上传人数 试用聚合做 √
+
     // 取得当前年份计划信息
     const setting = await this.setmodel.findOne();
     if (!setting) {
       throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认设置');
     }
-    console.log(moment().format('YYYY'));
-    const plan = await this.tmodel.findById(setting.planid);
-    if (!plan) {
-      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '当前全年计划不存在');
+    const { planid } = setting;
+    if (!planid) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认年度计划');
     }
-    // 根据计划取得当前年份下计划培训学生人数
-    const planstu = _.chain(plan.termnum).map('batchnum').flatten()
-      .map('number');
-    let _planstu = 0;
-    for (const el of planstu) {
-      _planstu = _.add(_planstu, parseInt(el));
+    const trainPlan = await this.tmodel.findById(planid);
+    if (!trainPlan) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认年度计划');
     }
-    const data = {};
-    data.planstu = _planstu;
-    // 根据计划取得学校上报的学生数
-    const schstus = await this.smodel.find({ planid: plan.id });
-    data.schstu = schstus.length;
-    // 统计各个学校
-    const _schools = _.map(schstus, 'school_name');
-    // 取得无重复的寝室号
-    const schools = _.uniq(_schools);
-    const schs = [];
-    for (const sch of schools) {
-      const _schstunum = schstus.filter(item => item.school_name === sch);
-      const newdata = { schname: sch, schnum: _schstunum.length };
-      schs.push(newdata);
+    let { termnum } = trainPlan;
+    if (!_.isArray(termnum)) {
+      throw new BusinessError(
+        ErrorCode.DATA_INVALID,
+        '默认年度计划的期数据格式不正确'
+      );
     }
+    // 转换下,因为之后用的期id不是ObjectId
+    termnum = JSON.parse(JSON.stringify(termnum));
+    const termids = termnum.map(i => i._id);
+    const data = {};
+    // 请假,退出
+    const levelqj = await this.ctx.model.Leave.count({
+      termid: { $in: termids },
+      type: '0',
+      status: '1',
+    });
+    const levelexit = await this.ctx.model.Leave.count({
+      termid: { $in: termids },
+      type: '1',
+      status: '1',
+    });
+    data.levelqj = levelqj || 0;
+    data.levelexit = levelexit || 0;
+    // 参加培训的学生
+    const trainstuRes = await this.ctx.model.Student.aggregate([
+      { $addFields: { u_id: { $toString: '$_id' } } },
+      { $match: { planid } },
+      {
+        $lookup: {
+          from: 'user',
+          localField: 'u_id',
+          foreignField: 'uid',
+          as: 'user',
+        },
+      },
+      { $match: { 'user.type': '4', 'user.openid': { $exists: true } } },
+      { $count: 'total' },
+    ]);
+    const h = _.head(trainstuRes);
+    const { total: trainstu } = h;
+    data.trainstu = trainstu;
+    // 已上传的学生总数
+    const schstu = await this.ctx.model.Student.count({ planid });
+    data.schstu = schstu;
+    // 未参加培训的学生
+    const notrainstu = schstu - trainstu;
+    data.notrainstu = notrainstu;
+    // 年度计划实际人数 这个还没用聚合,不是很优雅
+    const mid = await this.ctx.model.Schtime.find({ planid });
+    const planstu = mid.reduce((p, n) => p + n.arrange.reduce((np, nn) => np + (nn.number * 1 || 0), 0), 0);
+    data.planstu = planstu;
+    // 各个学校上传的人数
+    const schs = await this.ctx.model.Student.aggregate([
+      { $match: { planid } },
+      { $group: { _id: '$schid', sum: { $sum: 1 } } },
+      { $lookup: {
+        from: 'school',
+        localField: '_id',
+        foreignField: 'code',
+        as: 'school',
+      } },
+      { $unwind: '$school' },
+      { $project: { _id: 0, schname: '$school.name', schnum: '$sum' } },
+    ]);
     data.schs = schs;
-    // 取得计划内已培训的学生数
-    const trainstu = schstus.filter(item => item.openid);
-    data.trainstu = trainstu.length;
-    // 取得计划内未培训的学生数
-    const notrainstu = schstus.filter(item => !item.openid);
-    data.notrainstu = notrainstu.length;
-    // 取得学生请假数和退出数
-    const levelstus = [];
-    // 循环取得所有请假和退出的学生信息
-    for (const elm of trainstu) {
-      const level = await this.lmodel.findOne({ studentid: elm.id, status: '1' });
-      if (level) {
-        levelstus.push(level);
-      }
-    }
-    // 筛选出请假数和退出数
-    const levelqj = levelstus.filter(item => item.type === '0');
-    const levelexit = levelstus.filter(item => item.type === '1');
-    data.levelqj = levelqj.length;
-    data.levelexit = levelexit.length;
     return data;
   }