schedule.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { isNullOrUndefined, trimData } = require('naf-core').Util;
  4. const { BusinessError, ErrorCode } = require('naf-core').Error;
  5. const _ = require('lodash');
  6. const assert = require('assert');
  7. const { ObjectId } = require('mongoose').Types;
  8. // 赛程信息
  9. class ScheduleService extends CrudService {
  10. constructor(ctx) {
  11. super(ctx, 'schedule');
  12. this.model = this.ctx.model.Schedule;
  13. }
  14. /**
  15. * 通过团队创建人id查询赛程信息
  16. * @param {String} user_id 团队创建人id
  17. * @param {Object} options 查询附加参数
  18. */
  19. async getByTeamCreater({ user_id, ...query }, { skip = 0, limit = 0 } = {}) {
  20. // 用 id 查团队表 create_id:id; 获取团队id去查红方和蓝方的赛程信息
  21. const team = await this.ctx.model.Team.findOne({ create_id: user_id }, { _id: 1 });
  22. if (!team) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到该用户的团队信息');
  23. const condition = { $or: [{ red_id: team._id }, { blue_id: team._id }], ...query };
  24. const data = await this.model.find(condition).skip(parseInt(skip)).limit(parseInt(limit));
  25. const total = await this.model.count(condition);
  26. return { data, total };
  27. }
  28. async checkNeedNext(id) {
  29. const sch = await this.model.findById(id);
  30. const { red_branch, blue_branch, match_id, match_name, status } = sch;
  31. // 手动确定比赛结束,如果比赛不结束,那就不需要下面
  32. if (status !== '2') return;
  33. if (!red_branch || !blue_branch) return;
  34. // 有比分,有位置, 再看看同一轮其他比赛是不是有轮空的.有轮空的就不安排,没有轮空的就直接安排晋级比赛
  35. // 将胜利的队伍的属性取出来,以便下面生成新数据
  36. const winProp = [];
  37. const propList = [ 'id', 'name', 'logo', 'members' ];
  38. const winTeam = this.getWinTeam(sch);
  39. for (const p of propList) {
  40. winProp.push({ key: p, value: sch[`${winTeam}_${p}`] });
  41. }
  42. // 随便拿一个位置,主要是下面要用轮数去做查询
  43. const match_position = _.get(sch, 'red_position', _.get(sch, 'blue_position'));
  44. const mpl = match_position.split('-');
  45. const head = _.head(mpl);
  46. const mpReg = new RegExp(`${head}-`);
  47. const condition = { match_id, match_name, match_position: mpReg, is_bye: true };
  48. const has_bye = await this.model.count(condition);
  49. // 说明有轮空,让管理员去创建下一轮的所有比赛赛程
  50. if (has_bye > 1) return;
  51. /**
  52. * 没有轮空,直接创建比赛
  53. * 流程位置计算公式:
  54. * a:赛程轮数: _.head()
  55. * n:该轮队伍编号: _.last()
  56. * a - n/n+1 => a+1 - (n+1) / 2 ;
  57. * 条件: a>=1, n>=1 ,且n为奇数
  58. */
  59. const turn = parseInt(head) + 1;
  60. const last = _.last(mpl);
  61. let times;
  62. if (last % 2 > 0) {
  63. // 奇数,+1再/2 能算出下一轮的场次
  64. times = (parseInt(last) + 1) / 2;
  65. } else {
  66. times = parseInt(last) / 2;
  67. }
  68. const next_match_position = `${turn}-${times}`;
  69. // 先查询有没有 match_name: '晋级赛',
  70. let nextMatchCreateData = {
  71. match_id,
  72. match_name,
  73. match_position: next_match_position,
  74. };
  75. let nextMatch = await this.model.findOne(nextMatchCreateData);
  76. // 设置队伍数据的函数
  77. const setTeamData = (team, source) => {
  78. for (const obj of winProp) {
  79. const { key, value } = obj;
  80. source[`${team}_${key}`] = value;
  81. }
  82. return source;
  83. };
  84. if (nextMatch) {
  85. // 已经有了下场比赛的数据,做修改,将新数据放蓝队里
  86. // 修改,一定是将数据放入蓝队中,所以需要判断下蓝队和红队是不是一个队伍,看下id就行
  87. const nmRed_id = _.get(nextMatch, 'red_id');
  88. const winTeamId = _.get(
  89. winProp.find(f => f.key === 'id'),
  90. 'value'
  91. );
  92. if (nmRed_id === winTeamId) return;
  93. nextMatch = setTeamData('blue', nextMatch);
  94. await nextMatch.save();
  95. } else {
  96. // 没有,将数据放红队里
  97. nextMatchCreateData = setTeamData('red', nextMatchCreateData);
  98. await this.model.create(nextMatchCreateData);
  99. }
  100. }
  101. // 根据比分Object获取胜利的队伍
  102. getWinTeam(data) {
  103. const { red_branch = 0, blue_branch = 0 } = data;
  104. if (red_branch > blue_branch) return 'red';
  105. return 'blue';
  106. }
  107. }
  108. module.exports = ScheduleService;