statistics.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. const { ObjectId } = require('mongoose').Types;
  7. // 统计
  8. class StatisticsService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'statistics');
  11. }
  12. async match({ match_id }) {
  13. const teamList = await this.ctx.model.Matchteam.find({ match_id }, { logo: 1, team_name: 1, team_id: 1 });
  14. const resList = [];
  15. for (const team of teamList) {
  16. const { team_id } = team;
  17. const matchList = await this.ctx.model.Schedule.find({ match_id, $or: [{ red_id: team_id }, { blue_id: team_id }] });
  18. const res = this.computedTeam(matchList, team_id);
  19. const info = this.getOtherInfoFromList(matchList, team_id);
  20. resList.push({ ...res, ...info });
  21. }
  22. return resList;
  23. }
  24. async ranking() {
  25. const projecList = [ 'id', 'name', 'branch', 'integral', 'logo' ];
  26. const groups = [ 'red', 'blue' ];
  27. const projection = {};
  28. for (const g of groups) {
  29. for (const prop of projecList) {
  30. projection[`${g}_${prop}`] = 1;
  31. }
  32. }
  33. // 查出所有的比赛
  34. const list = await this.ctx.model.Schedule.find({}, projection);
  35. // console.log(list);
  36. // 统计出所有队伍(去重)
  37. const rts = list.map(f => f.red_id);
  38. const bts = list.map(f => f.blue_id);
  39. const teamList = _.uniq(_.compact([ ...rts, ...bts ]));
  40. const rList = [];
  41. for (const team_id of teamList) {
  42. // 获得这支队伍在所有比赛中的胜负情况及积分
  43. const res = this.computedTeam(list, team_id);
  44. const info = this.getOtherInfoFromList(list, team_id);
  45. rList.push({ ...info, ...res });
  46. }
  47. const winList = _.orderBy(rList, 'win', [ 'desc' ]);
  48. const scoreList = _.orderBy(rList, 'score', [ 'desc' ]);
  49. return { winList, scoreList };
  50. }
  51. /**
  52. * 根据队伍id,算出在范围内队伍的 胜负次数 及 积分
  53. * @param {Array} list 比赛列表
  54. * @param {String} team_id 队伍id
  55. */
  56. computedTeam(list, team_id) {
  57. let winTimes = 0; // 胜利次数
  58. let loseTimes = 0; // 失败次数
  59. let score = 0; // 积分
  60. for (const match of list) {
  61. const { red_id, blue_id, red_branch, blue_branch } = match;
  62. let teamInMatch = 'blue';
  63. if (red_id === team_id) teamInMatch = 'red';
  64. else if (blue_id === team_id) teamInMatch = 'blue';
  65. else {
  66. // 该队伍不是红蓝任意一方,说明不是这的,下一场
  67. continue;
  68. }
  69. // 加积分
  70. score += parseInt(match[`${teamInMatch}_integral`]) || 0;
  71. // 算胜负: winTeam => true : 红队胜;反之蓝队胜
  72. const winTeam = parseInt(red_branch) > parseInt(blue_branch);
  73. if (winTeam && teamInMatch === 'red') winTimes++;
  74. else if (!winTeam && teamInMatch !== 'red') winTimes++;
  75. else loseTimes++;
  76. }
  77. return { win: winTimes, lose: loseTimes, score };
  78. }
  79. /**
  80. * 根据比赛列表获取队伍信息
  81. * @param {Array} list 比赛列表
  82. * @param {String} team_id 队伍id
  83. */
  84. getOtherInfoFromList(list, team_id) {
  85. const match = list.find(f => f.red_id === team_id || f.blue_id === team_id);
  86. let logo = {};
  87. let name = '';
  88. if (match) {
  89. const { red_id } = match;
  90. if (red_id === team_id) {
  91. logo = match.red_logo;
  92. name = match.red_name;
  93. } else {
  94. logo = match.blue_logo;
  95. name = match.blue_name;
  96. }
  97. }
  98. return { logo, name };
  99. }
  100. }
  101. module.exports = StatisticsService;