|
@@ -0,0 +1,77 @@
|
|
|
|
+'use strict';
|
|
|
|
+const { CrudService } = require('naf-framework-mongoose-free/lib/service');
|
|
|
|
+const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
|
|
+const _ = require('lodash');
|
|
|
|
+const assert = require('assert');
|
|
|
|
+
|
|
|
|
+//
|
|
|
|
+class MatchTeamGroupService extends CrudService {
|
|
|
|
+ constructor(ctx) {
|
|
|
|
+ super(ctx, 'matchteamgroup');
|
|
|
|
+ this.model = this.ctx.model.Race.MatchTeamGroup;
|
|
|
|
+ this.matchProjectModel = this.ctx.model.Race.MatchProject;
|
|
|
|
+ this.teamApplyModel = this.ctx.model.Race.TeamApply;
|
|
|
|
+ this.matchSignModel = this.ctx.model.Race.MatchSign;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async saveAll(data) {
|
|
|
|
+ for (const i of data) {
|
|
|
|
+ const { _id } = i;
|
|
|
|
+ if (!_id) {
|
|
|
|
+ // TODO: 创建前:需要检查这些人员是否出现在这个项目中的别的组中
|
|
|
|
+ await this.model.create(i);
|
|
|
|
+ } else {
|
|
|
|
+ await this.model.updateOne({ _id }, i);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async auto({ match_id, group_id, project_id, team_number = 0 }) {
|
|
|
|
+ // 找到比赛项目
|
|
|
|
+ const project = await this.matchProjectModel.findById(project_id);
|
|
|
|
+ if (!project) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到比赛项目');
|
|
|
|
+ const { type } = project;
|
|
|
|
+ // type 为 1 双打,是TeamApply表中的, type 为2 单打,是User表
|
|
|
|
+ let personList = [];
|
|
|
|
+ const obj = { match_id, group_id, project_id };
|
|
|
|
+ if (type === '1') {
|
|
|
|
+ // 双打,找到这个项目所有的申请,且审核通过的
|
|
|
|
+ obj.person_type = 'TeamApply';
|
|
|
|
+ const teamApplys = await this.teamApplyModel.find({ project_id, pay_status: '1' });
|
|
|
|
+ personList = JSON.parse(JSON.stringify(teamApplys));
|
|
|
|
+ } else {
|
|
|
|
+ // 单打,找到这个项目所有申请报名的信息
|
|
|
|
+ obj.person_type = 'User';
|
|
|
|
+ const sign = await this.matchSignModel.find({ project_id, pay_status: '1' });
|
|
|
|
+ personList = JSON.parse(JSON.stringify(sign));
|
|
|
|
+ }
|
|
|
|
+ const returnData = [];
|
|
|
|
+ // 选手数检测
|
|
|
|
+ const number = _.floor(_.divide(personList.length, team_number));
|
|
|
|
+ if (number <= 0) throw new BusinessError(ErrorCode.DATA_INVALID, '选手不足以分组,要分组的总人数 至少为 要分的组数');
|
|
|
|
+ // 选手列表分组
|
|
|
|
+ const teams = _.chunk(personList, number);
|
|
|
|
+ // 获取 选手被均分到每个组后的余数
|
|
|
|
+ const el = personList.length % team_number;
|
|
|
|
+ // 最后余下的组数据
|
|
|
|
+ let last = [];
|
|
|
|
+ if (el !== 0) {
|
|
|
|
+ // 如果有剩余不能被均分的选手,则将这些选手 放到 last数组中,再将多出来的这个去掉
|
|
|
|
+ last = _.last(teams);
|
|
|
|
+ teams.pop();
|
|
|
|
+ }
|
|
|
|
+ // 将正常均分的小组先分出来
|
|
|
|
+ for (let i = 0; i < teams.length; i++) {
|
|
|
|
+ const t = { name: `小组${i + 1}`, person: teams[i], ...obj };
|
|
|
|
+ returnData.push(t);
|
|
|
|
+ }
|
|
|
|
+ // 循环剩下的选手, 依次放入每个已经分好的组中,尽可能均分人数
|
|
|
|
+ for (let i = 0; i < last.length; i++) {
|
|
|
|
+ returnData[i].person.push(last[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return returnData;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+module.exports = MatchTeamGroupService;
|