lrf 3 лет назад
Родитель
Сommit
6893d13765

+ 55 - 53
app/controller/.matchteam.js

@@ -1,80 +1,82 @@
 module.exports = {
   create: {
     requestBody: [
-      "match_id",
-      "match_name",
-      "team_id",
-      "team_name",
-      "logo",
-      "create_id",
-      "create_user",
-      "create_time",
-      "members",
-      "match_num",
-      "apply_time",
-      "win",
-      "shu",
-      "integral",
-      "rank",
-      "status",
-      "remark",
+      'match_id',
+      'match_name',
+      'team_id',
+      'team_name',
+      'logo',
+      'create_id',
+      'create_user',
+      'create_time',
+      'members',
+      'match_num',
+      'apply_time',
+      'win',
+      'shu',
+      'integral',
+      'rank',
+      'status',
+      'format',
+      'remark',
     ],
   },
   destroy: {
-    params: ["!id"],
-    service: "delete",
+    params: ['!id'],
+    service: 'delete',
   },
   update: {
-    params: ["!id"],
+    params: ['!id'],
     requestBody: [
-      "match_id",
-      "match_name",
-      "team_id",
-      "team_name",
-      "logo",
-      "create_id",
-      "create_user",
-      "create_time",
-      "members",
-      "match_num",
-      "apply_time",
-      "win",
-      "shu",
-      "integral",
-      "rank",
-      "status",
-      "remark",
+      'match_id',
+      'match_name',
+      'team_id',
+      'team_name',
+      'logo',
+      'create_id',
+      'create_user',
+      'create_time',
+      'members',
+      'match_num',
+      'apply_time',
+      'win',
+      'shu',
+      'integral',
+      'rank',
+      'status',
+      'format',
+      'remark',
     ],
   },
   show: {
     parameters: {
-      params: ["!id"],
+      params: ['!id'],
     },
-    service: "fetch",
+    service: 'fetch',
   },
   index: {
     parameters: {
       query: {
-        match_id: "match_id",
-        match_name: "match_name",
-        team_id: "team_id",
-        team_name: "team_name",
-        create_id: "create_id",
-        create_user: "create_user",
-        create_time: "create_time",
-        apply_time: "apply_time",
-        status: "status",
-        "meta.createdAt@start": "meta.createdAt@start",
-        "meta.createdAt@end": "meta.createdAt@end",
+        match_id: 'match_id',
+        match_name: 'match_name',
+        team_id: 'team_id',
+        team_name: 'team_name',
+        create_id: 'create_id',
+        create_user: 'create_user',
+        create_time: 'create_time',
+        apply_time: 'apply_time',
+        status: 'status',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
       },
       // options: {
       //   "meta.state": 0 // 默认条件
       // },
     },
-    service: "query",
+    service: 'query',
     options: {
-      query: ["skip", "limit"],
-      sort: ["meta.createdAt"],
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
       desc: true,
       count: true,
     },

+ 58 - 54
app/controller/.schedule.js

@@ -1,81 +1,85 @@
 module.exports = {
   create: {
     requestBody: [
-      "match_id",
-      "match_name",
-      "red_id",
-      "red_name",
-      "red_logo",
-      "red_members",
-      "red_branch",
-      "red_integral",
-      "blue_id",
-      "blue_name",
-      "blue_logo",
-      "blue_members",
-      "blue_branch",
-      "blue_integral",
-      "match_time",
-      "match_file",
-      "status",
-      "remark",
+      'match_id',
+      'match_name',
+      'red_id',
+      'red_name',
+      'red_logo',
+      'red_members',
+      'red_branch',
+      'red_integral',
+      'blue_id',
+      'blue_name',
+      'blue_logo',
+      'blue_members',
+      'blue_branch',
+      'blue_integral',
+      'match_time',
+      'match_file',
+      'status',
+      'remark',
+      'match_position',
+      'is_bye',
     ],
   },
   destroy: {
-    params: ["!id"],
-    service: "delete",
+    params: ['!id'],
+    service: 'delete',
   },
   update: {
-    params: ["!id"],
+    params: ['!id'],
     requestBody: [
-      "match_id",
-      "match_name",
-      "red_id",
-      "red_name",
-      "red_logo",
-      "red_members",
-      "red_branch",
-      "red_integral",
-      "blue_id",
-      "blue_name",
-      "blue_logo",
-      "blue_members",
-      "blue_branch",
-      "blue_integral",
-      "match_time",
-      "match_file",
-      "status",
-      "remark",
+      'match_id',
+      'match_name',
+      'red_id',
+      'red_name',
+      'red_logo',
+      'red_members',
+      'red_branch',
+      'red_integral',
+      'blue_id',
+      'blue_name',
+      'blue_logo',
+      'blue_members',
+      'blue_branch',
+      'blue_integral',
+      'match_time',
+      'match_file',
+      'status',
+      'remark',
+      'match_position',
+      'is_bye',
     ],
   },
   show: {
     parameters: {
-      params: ["!id"],
+      params: ['!id'],
     },
-    service: "fetch",
+    service: 'fetch',
   },
   index: {
     parameters: {
       query: {
-        match_id: "match_id",
-        match_name: "match_name",
-        red_id: "red_id",
-        red_name: "red_name",
-        blue_id: "blue_id",
-        blue_name: "blue_name",
-        match_time: "match_time",
-        status: "status",
-        "meta.createdAt@start": "meta.createdAt@start",
-        "meta.createdAt@end": "meta.createdAt@end",
+        match_id: 'match_id',
+        match_name: 'match_name',
+        red_id: 'red_id',
+        red_name: 'red_name',
+        blue_id: 'blue_id',
+        blue_name: 'blue_name',
+        match_time: 'match_time',
+        status: 'status',
+        'meta.createdAt@start': 'meta.createdAt@start',
+        'meta.createdAt@end': 'meta.createdAt@end',
       },
       // options: {
       //   "meta.state": 0 // 默认条件
       // },
     },
-    service: "query",
+    service: 'query',
     options: {
-      query: ["skip", "limit"],
-      sort: ["meta.createdAt"],
+      query: ['skip', 'limit'],
+      sort: ['meta.createdAt'],
       desc: true,
       count: true,
     },

+ 10 - 0
app/middleware/schedule.js

@@ -0,0 +1,10 @@
+'use strict';
+const _ = require('lodash');
+module.exports = options => {
+  return async function schedule(ctx, next) {
+    await next();
+    // 进入处理修改逻辑
+    const id = ctx.params.id;
+    await ctx.service.schedule.checkNeedNext(id);
+  };
+};

+ 1 - 0
app/model/matchteam.js

@@ -21,6 +21,7 @@ const matchteam = {
   integral: { type: String }, // 积分
   rank: { type: String }, // 名次
   status: { type: String, default: '0' }, // 状态
+  format: { type: Array }, // 赛制
   remark: { type: String },
 };
 const schema = new Schema(matchteam, { toJSON: { virtuals: true } });

+ 3 - 0
app/model/schedule.js

@@ -24,6 +24,9 @@ const schedule = {
   match_time: { type: String }, // 比赛时间
   match_file: { type: Array }, // 比赛图片
   status: { type: String, default: '0' }, // 状态
+
+  match_position: { type: String }, // 比赛流程图位置,可以用来计算晋级后的位置
+  is_bye: { type: Boolean, default: false }, // 是否轮空, 轮空只有1个队伍
   remark: { type: String },
 };
 const schema = new Schema(schedule, { toJSON: { virtuals: true } });

+ 17 - 0
app/router.js

@@ -3,8 +3,25 @@
 /**
  * @param {Egg.Application} app - egg application
  */
+
+const os = require('os');
+function getIPAdress() {
+  const interfaces = os.networkInterfaces();
+  for (const devName in interfaces) {
+    const iface = interfaces[devName];
+    for (let i = 0; i < iface.length; i++) {
+      const alias = iface[i];
+      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
+        return alias.address;
+      }
+    }
+  }
+}
 module.exports = app => {
   const { router, controller } = app;
+  const { routePrefix, cluster } = app.config;
+  const ipAddress = getIPAdress();
+  console.log(`前缀:http://${ipAddress}:${cluster.listen.port}${routePrefix}`);
   router.get('/', controller.home.index);
   router.post('/courtAdmin/api/admin/login', controller.home.login);
   router.get('/courtAdmin/api/useradmin', controller.admin.index);

+ 70 - 0
app/service/schedule.js

@@ -1,8 +1,10 @@
 '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 {
@@ -10,6 +12,74 @@ class ScheduleService extends CrudService {
     super(ctx, 'schedule');
     this.model = this.ctx.model.Schedule;
   }
+
+  async checkNeedNext(id) {
+    const sch = await this.model.findById(id);
+    const { red_branch, blue_branch, match_position, match_id } = sch;
+    if (!red_branch || !blue_branch) return;
+    if (!match_position) console.error(`Schedule表: id: ${id} 数据缺少流程位置`);
+    // 有比分,有位置, 再看看同一轮其他比赛是不是有轮空的.有轮空的就不安排,没有轮空的就直接安排晋级比赛
+    // 将胜利的队伍的属性取出来,以便下面生成新数据
+    const winProp = [];
+    const propList = [ 'id', 'name', 'logo', 'members' ];
+    let winTeam = 'blue';
+    if (red_branch > blue_branch) winTeam = 'red';
+    for (const p of propList) {
+      winProp.push({ key: p, value: sch[`${winTeam}_${p}`] });
+    }
+    const mpl = match_position.split('-');
+    const head = _.head(mpl);
+    const mpReg = new RegExp(`${head}-`);
+    const condition = { match_id, 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_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);
+    }
+  }
 }
 
 module.exports = ScheduleService;

+ 1 - 1
app/z_router/schedule.js

@@ -7,7 +7,7 @@ const routes = [
   { method: 'get', path: `${rkey}`, controller: `${ckey}.index`, name: `${ckey}Query`, zh: `${keyZh}列表查询` },
   { method: 'get', path: `${rkey}/:id`, controller: `${ckey}.show`, name: `${ckey}Show`, zh: `${keyZh}查询` },
   { method: 'post', path: `${rkey}`, controller: `${ckey}.create`, middleware: [ 'password' ], name: `${ckey}Create`, zh: `创建${keyZh}` },
-  { method: 'post', path: `${rkey}/:id`, controller: `${ckey}.update`, name: `${ckey}Update`, zh: `修改${keyZh}` },
+  { method: 'post', path: `${rkey}/:id`, controller: `${ckey}.update`, middleware: [ 'schedule' ], name: `${ckey}Update`, zh: `修改${keyZh}` },
   { method: 'delete', path: `${rkey}/:id`, controller: `${ckey}.destroy`, name: `${ckey}Delete`, zh: `删除${keyZh}` },
 ];
 

+ 43 - 0
test/test.js

@@ -0,0 +1,43 @@
+'use strict';
+const limit = 6;
+// for (let i = limit; i <= limit; i++) {
+//   const r1 = limit % 2;
+//   if (r1 > 0) {
+//     // 奇数
+//     const mid = (limit - 1) / 2;
+//   } else {
+//     // 偶数
+//   }
+// }
+const loop = ({ limit, els = 0 }) => {
+  if (limit === 1 && els === 0) {
+    console.log('比赛结束');
+    return;
+  }
+  const r1 = (limit + els) % 2;
+  let mid;
+  if (r1 > 0) {
+    // 奇数
+    mid = (limit + els - 1) / 2;
+    els = 1;
+    console.log('轮空1支队伍');
+    console.log(`奇数:limit:${mid};els:${els}`);
+  } else {
+    // 偶数
+    mid = (limit + els) / 2;
+    els = 0;
+    console.log(`偶数:limit:${mid};els:${els}`);
+  }
+  return { limit: mid, els };
+};
+
+for (let i = 5; i <= 20; i++) {
+  console.group(`${i} 支队伍开始淘汰`);
+  let m;
+  m = loop({ limit: i });
+  while (m) {
+    m = loop(m);
+  }
+  console.groupEnd(`${i} 支队伍淘汰结束`);
+}
+