123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- 'use strict';
- const { CrudService } = require('naf-framework-mongoose-free/lib/service');
- const { isNullOrUndefined, trimData } = require('naf-core').Util;
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const _ = require('lodash');
- const assert = require('assert');
- const { ObjectId } = require('mongoose').Types;
- // 赛程信息
- class ScheduleService extends CrudService {
- constructor(ctx) {
- super(ctx, 'schedule');
- this.model = this.ctx.model.Schedule;
- }
- /**
- * 通过团队创建人id查询赛程信息
- * @param {String} user_id 团队创建人id
- * @param {Object} options 查询附加参数
- */
- async getByTeamCreater({ user_id, ...query }, { skip = 0, limit = 0 } = {}) {
- // 用 id 查团队表 create_id:id; 获取团队id去查红方和蓝方的赛程信息
- const team = await this.ctx.model.Team.findOne({ create_id: user_id }, { _id: 1 });
- if (!team) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到该用户的团队信息');
- const condition = { $or: [{ red_id: team._id }, { blue_id: team._id }], ...query };
- const data = await this.model.find(condition).skip(parseInt(skip)).limit(parseInt(limit));
- const total = await this.model.count(condition);
- return { data, total };
- }
- async checkNeedNext(id) {
- const sch = await this.model.findById(id);
- const { red_branch, blue_branch, match_id, match_name, status } = sch;
- // 手动确定比赛结束,如果比赛不结束,那就不需要下面
- if (status !== '2') return;
- if (!red_branch || !blue_branch) return;
- // 有比分,有位置, 再看看同一轮其他比赛是不是有轮空的.有轮空的就不安排,没有轮空的就直接安排晋级比赛
- // 将胜利的队伍的属性取出来,以便下面生成新数据
- const winProp = [];
- const propList = [ 'id', 'name', 'logo', 'members' ];
- const winTeam = this.getWinTeam(sch);
- for (const p of propList) {
- winProp.push({ key: p, value: sch[`${winTeam}_${p}`] });
- }
- // 随便拿一个位置,主要是下面要用轮数去做查询
- const match_position = _.get(sch, 'red_position', _.get(sch, 'blue_position'));
- const mpl = match_position.split('-');
- const head = _.head(mpl);
- const mpReg = new RegExp(`${head}-`);
- const condition = { match_id, match_name, match_position: mpReg, is_bye: true };
- const has_bye = await this.model.count(condition);
- // 说明有轮空,让管理员去创建下一轮的所有比赛赛程
- if (has_bye > 1) return;
- /**
- * 没有轮空,直接创建比赛
- * 流程位置计算公式:
- * a:赛程轮数: _.head()
- * n:该轮队伍编号: _.last()
- * a - n/n+1 => a+1 - (n+1) / 2 ;
- * 条件: a>=1, n>=1 ,且n为奇数
- */
- const turn = parseInt(head) + 1;
- const last = _.last(mpl);
- let times;
- if (last % 2 > 0) {
- // 奇数,+1再/2 能算出下一轮的场次
- times = (parseInt(last) + 1) / 2;
- } else {
- times = parseInt(last) / 2;
- }
- const next_match_position = `${turn}-${times}`;
- // 先查询有没有 match_name: '晋级赛',
- let nextMatchCreateData = {
- match_id,
- match_name,
- match_position: next_match_position,
- };
- let nextMatch = await this.model.findOne(nextMatchCreateData);
- // 设置队伍数据的函数
- const setTeamData = (team, source) => {
- for (const obj of winProp) {
- const { key, value } = obj;
- source[`${team}_${key}`] = value;
- }
- return source;
- };
- if (nextMatch) {
- // 已经有了下场比赛的数据,做修改,将新数据放蓝队里
- // 修改,一定是将数据放入蓝队中,所以需要判断下蓝队和红队是不是一个队伍,看下id就行
- const nmRed_id = _.get(nextMatch, 'red_id');
- const winTeamId = _.get(
- winProp.find(f => f.key === 'id'),
- 'value'
- );
- if (nmRed_id === winTeamId) return;
- nextMatch = setTeamData('blue', nextMatch);
- await nextMatch.save();
- } else {
- // 没有,将数据放红队里
- nextMatchCreateData = setTeamData('red', nextMatchCreateData);
- await this.model.create(nextMatchCreateData);
- }
- }
- // 根据比分Object获取胜利的队伍
- getWinTeam(data) {
- const { red_branch = 0, blue_branch = 0 } = data;
- if (red_branch > blue_branch) return 'red';
- return 'blue';
- }
- }
- module.exports = ScheduleService;
|