schedule.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. async checkNeedNext(id) {
  15. const sch = await this.model.findById(id);
  16. const { red_branch, blue_branch, match_position, match_id } = sch;
  17. if (!red_branch || !blue_branch) return;
  18. if (!match_position) console.error(`Schedule表: id: ${id} 数据缺少流程位置`);
  19. // 有比分,有位置, 再看看同一轮其他比赛是不是有轮空的.有轮空的就不安排,没有轮空的就直接安排晋级比赛
  20. // 将胜利的队伍的属性取出来,以便下面生成新数据
  21. const winProp = [];
  22. const propList = [ 'id', 'name', 'logo', 'members' ];
  23. let winTeam = 'blue';
  24. if (red_branch > blue_branch) winTeam = 'red';
  25. for (const p of propList) {
  26. winProp.push({ key: p, value: sch[`${winTeam}_${p}`] });
  27. }
  28. const mpl = match_position.split('-');
  29. const head = _.head(mpl);
  30. const mpReg = new RegExp(`${head}-`);
  31. const condition = { match_id, match_position: mpReg, is_bye: true };
  32. const has_bye = await this.model.count(condition);
  33. // 说明有轮空,让管理员去创建下一轮的所有比赛赛程
  34. if (has_bye > 1) return;
  35. /**
  36. * 没有轮空,直接创建比赛
  37. * 流程位置计算公式:
  38. * a:赛程轮数: _.head()
  39. * n:该轮场次编号: _.last()
  40. * a - n/n+1 => a+1 - (n+1) / 2 ;
  41. * 条件: a>=1, n>=1 ,且n为奇数
  42. */
  43. const turn = parseInt(head) + 1;
  44. const last = _.last(mpl);
  45. let times;
  46. if (last % 2 > 0) {
  47. // 奇数,+1再/2 能算出下一轮的场次
  48. times = (parseInt(last) + 1) / 2;
  49. } else {
  50. times = parseInt(last) / 2;
  51. }
  52. const next_match_position = `${turn}-${times}`;
  53. // 先查询有没有 match_name: '晋级赛',
  54. let nextMatchCreateData = {
  55. match_id,
  56. match_position: next_match_position,
  57. };
  58. let nextMatch = await this.model.findOne(nextMatchCreateData);
  59. // 设置队伍数据的函数
  60. const setTeamData = (team, source) => {
  61. for (const obj of winProp) {
  62. const { key, value } = obj;
  63. source[`${team}_${key}`] = value;
  64. }
  65. return source;
  66. };
  67. if (nextMatch) {
  68. // 已经有了下场比赛的数据,做修改,将新数据放蓝队里
  69. // 修改,一定是将数据放入蓝队中,所以需要判断下蓝队和红队是不是一个队伍,看下id就行
  70. const nmRed_id = _.get(nextMatch, 'red_id');
  71. const winTeamId = _.get(winProp.find(f => f.key === 'id'), 'value');
  72. if (nmRed_id === winTeamId) return;
  73. nextMatch = setTeamData('blue', nextMatch);
  74. await nextMatch.save();
  75. } else {
  76. // 没有,将数据放红队里
  77. nextMatchCreateData = setTeamData('red', nextMatchCreateData);
  78. await this.model.create(nextMatchCreateData);
  79. }
  80. }
  81. }
  82. module.exports = ScheduleService;