|
@@ -81,13 +81,18 @@ class CountService extends CrudService {
|
|
|
{ $count: 'total' },
|
|
|
]);
|
|
|
const h = _.head(trainstuRes);
|
|
|
- const { total: trainstu } = h;
|
|
|
- data.trainstu = trainstu;
|
|
|
+ if (h) {
|
|
|
+ const { total: trainstu } = h;
|
|
|
+ data.trainstu = trainstu;
|
|
|
+ } else {
|
|
|
+ data.trainstu = 0;
|
|
|
+ }
|
|
|
+
|
|
|
// 已上传的学生总数
|
|
|
const schstu = await this.ctx.model.Student.count({ planid });
|
|
|
data.schstu = schstu;
|
|
|
// 未参加培训的学生
|
|
|
- const notrainstu = schstu - trainstu;
|
|
|
+ const notrainstu = schstu - data.trainstu;
|
|
|
data.notrainstu = notrainstu;
|
|
|
// 年度计划实际人数 这个还没用聚合,不是很优雅
|
|
|
const mid = await this.ctx.model.Schtime.find({ planid });
|
|
@@ -112,43 +117,87 @@ class CountService extends CrudService {
|
|
|
|
|
|
// 按学校id统计查询
|
|
|
async countschstu({ id }) {
|
|
|
- console.log(id);
|
|
|
+ // levelexit:退出人数 √
|
|
|
+ // levelqj:请假人数 √
|
|
|
+ // notrainstu:上传名单,但是未培训人数 student表中的数据不稳,后加的可能没有了.被人绑定更换也可能没有了.所以 这个数字用 student.total - user(type=4&&openid) 的结果 √
|
|
|
+ // schstu:上传名单人数 该年度计划下,的student.total √
|
|
|
+ // trainstu:已参加培训人数 user(type==4&&openid).total √
|
|
|
+ // planstu:年度计划人数(重算) 根据年度计划学校的分配计算 √
|
|
|
// 取得当前年份计划信息
|
|
|
- console.log(moment().format('YYYY'));
|
|
|
- const plan = await this.tmodel.findOne({ year: moment().format('YYYY') });
|
|
|
- if (!plan) {
|
|
|
- throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '当前全年计划不存在');
|
|
|
+ const setting = await this.setmodel.findOne();
|
|
|
+ if (!setting) {
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认设置');
|
|
|
+ }
|
|
|
+ const { planid } = setting;
|
|
|
+ if (!planid) {
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认年度计划');
|
|
|
+ }
|
|
|
+ const trainPlan = await this.tmodel.findById(planid);
|
|
|
+ if (!trainPlan) {
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '没有找到默认年度计划');
|
|
|
}
|
|
|
- // 根据计划取得当前年份下计划学校培训学生人数
|
|
|
- const school = await this.schmodel.findOne({ code: id });
|
|
|
- if (!school) {
|
|
|
- throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '学校信息不存在');
|
|
|
+ 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 = {};
|
|
|
- data.planstu = school.number;
|
|
|
- // 根据学校id取得学校上报的学生数
|
|
|
- const schstus = await this.smodel.find({ planid: plan.id, schid: id });
|
|
|
- data.schstu = schstus.length;
|
|
|
- // 取得已培训的学生数
|
|
|
- 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 = await this.ctx.model.Leave.count({
|
|
|
+ termid: { $in: termids },
|
|
|
+ type: '0',
|
|
|
+ status: '1',
|
|
|
+ schid: id,
|
|
|
+ });
|
|
|
+ const levelexit = await this.ctx.model.Leave.count({
|
|
|
+ termid: { $in: termids },
|
|
|
+ type: '1',
|
|
|
+ status: '1',
|
|
|
+ schid: id,
|
|
|
+ });
|
|
|
+ data.levelqj = levelqj || 0;
|
|
|
+ data.levelexit = levelexit || 0;
|
|
|
+ // 参加培训的学生
|
|
|
+ const trainstuRes = await this.ctx.model.Student.aggregate([
|
|
|
+ { $addFields: { u_id: { $toString: '$_id' } } },
|
|
|
+ { $match: { planid, schid: id } },
|
|
|
+ {
|
|
|
+ $lookup: {
|
|
|
+ from: 'user',
|
|
|
+ localField: 'u_id',
|
|
|
+ foreignField: 'uid',
|
|
|
+ as: 'user',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { $match: { 'user.type': '4', 'user.openid': { $exists: true } } },
|
|
|
+ { $count: 'total' },
|
|
|
+ ]);
|
|
|
+ const h = _.head(trainstuRes);
|
|
|
+ if (h) {
|
|
|
+ const { total: trainstu } = h;
|
|
|
+ data.trainstu = trainstu;
|
|
|
+ } else {
|
|
|
+ data.trainstu = 0;
|
|
|
}
|
|
|
- // 筛选出请假数和退出数
|
|
|
- const levelqj = levelstus.filter(item => item.type === '0');
|
|
|
- const levelexit = levelstus.filter(item => item.type === '1');
|
|
|
- data.levelqj = levelqj.length;
|
|
|
- data.levelexit = levelexit.length;
|
|
|
+
|
|
|
+ // 已上传的学生总数
|
|
|
+ const schstu = await this.ctx.model.Student.count({ planid, schid: id });
|
|
|
+ data.schstu = schstu;
|
|
|
+ // 未参加培训的学生
|
|
|
+ const notrainstu = schstu - data.trainstu;
|
|
|
+ data.notrainstu = notrainstu;
|
|
|
+ // 年度计划实际人数 这个还没用聚合,不是很优雅
|
|
|
+ const mid = await this.ctx.model.Schtime.find({ planid, schid: id });
|
|
|
+ const planstu = mid.reduce(
|
|
|
+ (p, n) => p + n.arrange.reduce((np, nn) => np + (nn.number * 1 || 0), 0),
|
|
|
+ 0
|
|
|
+ );
|
|
|
+ data.planstu = planstu;
|
|
|
return data;
|
|
|
}
|
|
|
|