count.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. const moment = require('moment');
  7. // 统计
  8. class CountService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'count');
  11. this.model = this.ctx.model.Count;
  12. this.refute = this.ctx.model.Refute;
  13. this.service = this.ctx.model.Service;
  14. this.topic = this.ctx.model.Topic;
  15. }
  16. /**
  17. * 首页统计
  18. */
  19. async index() {
  20. // 本周的文章发表数量,折线图,3条线,没有的天也需要日期,默认值为0:模型(数据过滤)
  21. const articles = await this.articleSum();
  22. // 3种类型各自的总阅读数
  23. const reads = await this.readSum();
  24. return { articles, reads };
  25. }
  26. /**
  27. * 本周的文章发表数量
  28. */
  29. async articleSum() {
  30. // TODO 查询本周的周一至周日的日期
  31. // 聚合函数查询本周发表的数量,按日期分组(应该需要加一个字段,单纯的是年月日) 'YYYY-MM-DD'
  32. const refute = await this.getWeekResult('refute');
  33. const serve = await this.getWeekResult('service');
  34. const topic = await this.getWeekResult('topic');
  35. return { refute, serve, topic };
  36. }
  37. /**
  38. * 根据表名查出一周的发表数量
  39. * @param {String} model 表名
  40. * @return {Array} arr
  41. */
  42. async getWeekResult(model) {
  43. const weekday = moment().weekday() - 1;
  44. // 因为时区问题查询条件需要在00:00:00的基础上减去8小时,将查询条件也变成GMT时间
  45. const start = moment(`${moment().subtract(weekday, 'days')
  46. .format('YYYY-MM-DD')} 00:00:00`).subtract(8, 'hours').format();
  47. const end = moment(`${moment().add(7 - weekday, 'days')
  48. .format('YYYY-MM-DD')} 00:00:00`).subtract(8, 'hours').format();
  49. const res = await this[model].aggregate([
  50. { $match: { 'meta.createdAt': { $gte: new Date(start), $lt: new Date(end) } } },
  51. {
  52. $project: {
  53. // meta的时间因为时区问题,差8个小时,加回来
  54. date: { $substr: [{ $add: [ '$meta.createdAt', 28800000 ] }, 0, 10 ] },
  55. },
  56. },
  57. {
  58. $group: {
  59. _id: '$date',
  60. sum: { $sum: 1 },
  61. },
  62. },
  63. ]);
  64. const arr = [];
  65. // 将本周每天都填充上
  66. for (let i = 1; i <= 7; i++) {
  67. const date = moment(start).add(i, 'days').format('YYYY-MM-DD');
  68. const r = res.find(f => _.isEqual(f._id, date));
  69. if (r) arr.push({ date, sum: r.sum });
  70. else arr.push({ date, sum: 0 });
  71. }
  72. return arr;
  73. }
  74. /**
  75. * 3种类型各自的总阅读数
  76. */
  77. async readSum() {
  78. // 查出各自的阅读数,聚合加和
  79. const refute = await this.getReadSum('refute');
  80. const serve = await this.getReadSum('service');
  81. const topic = await this.getReadSum('topic');
  82. return { refute, serve, topic };
  83. }
  84. async getReadSum(model) {
  85. const result = await this[model].aggregate([
  86. { $project: { _id: 1, read: 1 } },
  87. { $group: {
  88. _id: '',
  89. read: { $sum: '$read' },
  90. } },
  91. ]);
  92. let res = 0;
  93. if (result.length > 0) {
  94. res = _.get(_.head(result), 'read', 0);
  95. }
  96. return res;
  97. }
  98. }
  99. module.exports = CountService;