赛会自动排班

pull/371/head
wuyibo 3 years ago
parent 0206ffc298
commit f080128a5a

@ -51,4 +51,9 @@ public class CacheConstants
* redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* key
*/
public static final String ARRANGE_TEAM_GROUP_SCHEDULE="arrange:team:group:schedule:";
}

@ -1,8 +1,8 @@
package com.ruoyi.system.controller;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -91,7 +91,13 @@ public class CompetitionTeamGroupController extends BaseController
{
return toAjax(competitionTeamGroupService.updateCompetitionTeamGroup(competitionTeamGroup));
}
@RequiresPermissions("system:competitionTeamGroup:arrangeTeamGroupSchedule")
@Log(title = "赛会中-一键编排分组内的球队的单组循环赛赛程", businessType = BusinessType.OTHER)
@PostMapping("/arrangeTeamGroupSchedule")
public AjaxResult arrangeTeamGroupSchedule(@RequestBody CompetitionTeamGroup competitionTeamGroup)
{
return toAjax(competitionTeamGroupService.arrangeTeamGroupSchedule(competitionTeamGroup));
}
/**
* -
*/

@ -0,0 +1,16 @@
package com.ruoyi.system.domain.vo;
import com.ruoyi.system.domain.CompetitionTeamVsTeam;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
*
*/
@Setter
@Getter
public class BegerArrangementVo {
private Integer round;
private List<CompetitionTeamVsTeam> vsTeamList;
}

@ -59,4 +59,11 @@ public interface CompetitionTeamVsTeamMapper
* @return
*/
public int deleteCompetitionTeamVsTeamByIds(Long[] ids);
/**
* -VS
*
* @param teamVsTeam
* @return
*/
public int updateCompetitionTeamVsTeamByCondition(CompetitionTeamVsTeam teamVsTeam);
}

@ -1,6 +1,7 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.CompetitionTeamGroup;
/**
@ -58,4 +59,6 @@ public interface ICompetitionTeamGroupService
* @return
*/
public int deleteCompetitionTeamGroupById(Long id);
//赛会中-一键编排分组内的球队的单组循环赛赛程
public Boolean arrangeTeamGroupSchedule(CompetitionTeamGroup competitionTeamGroup);
}

@ -1,11 +1,29 @@
package com.ruoyi.system.service.impl;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.domain.Competition;
import com.ruoyi.system.domain.CompetitionOfTeam;
import com.ruoyi.system.domain.CompetitionTeamVsTeam;
import com.ruoyi.system.domain.vo.BegerArrangementVo;
import com.ruoyi.system.domain.vo.CompetitionOfTeamVo;
import com.ruoyi.system.domain.vo.CompetitionTeamVsTeamVo;
import com.ruoyi.system.mapper.CompetitionMapper;
import com.ruoyi.system.mapper.CompetitionOfTeamMapper;
import com.ruoyi.system.mapper.CompetitionTeamVsTeamMapper;
import com.ruoyi.system.utils.BegerSingleCycleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CompetitionTeamGroupMapper;
import com.ruoyi.system.domain.CompetitionTeamGroup;
import com.ruoyi.system.service.ICompetitionTeamGroupService;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
/**
* -Service
@ -16,9 +34,16 @@ import com.ruoyi.system.service.ICompetitionTeamGroupService;
@Service
public class CompetitionTeamGroupServiceImpl implements ICompetitionTeamGroupService
{
@Autowired
@Resource
private CompetitionTeamGroupMapper competitionTeamGroupMapper;
@Resource
private RedisService redisService;
@Resource
private CompetitionMapper competitionMapper;
@Resource
private CompetitionOfTeamMapper competitionOfTeamMapper;
@Resource
private CompetitionTeamVsTeamMapper competitionTeamVsTeamMapper;
/**
* -
*
@ -90,4 +115,66 @@ public class CompetitionTeamGroupServiceImpl implements ICompetitionTeamGroupSer
{
return competitionTeamGroupMapper.deleteCompetitionTeamGroupById(id);
}
@Override
public Boolean arrangeTeamGroupSchedule(CompetitionTeamGroup competitionTeamGroup) {
//todo 加锁防止重复的点编排赛程
Object isLock = redisService.getCacheObject(CacheConstants.ARRANGE_TEAM_GROUP_SCHEDULE + competitionTeamGroup.getId());
if(!StringUtils.isEmpty(isLock)){
throw new ServiceException("系统正在努力的对当前分组的球队进行赛程编排,请稍等片刻");
}else {
Boolean bool =false;
CompetitionTeamGroup teamGroup = competitionTeamGroupMapper.selectCompetitionTeamGroupById(competitionTeamGroup.getId());
if(teamGroup.getIsCycle().intValue()==1){
throw new ServiceException("当前分组中的球队已经编排过了。无需重复操作");
}
//获取比赛时间
Competition competition = competitionMapper.selectCompetitionById(teamGroup.getCompetitionId());
Date competitionBeginTime = competition.getCompetitionBeginTime();
Calendar calendar = new GregorianCalendar();
calendar.setTime(competitionBeginTime);
calendar.add(Calendar.DATE,1); //把日期往后增加一天,整数 往后推,负数往前移动
//按报名优先级来排序
CompetitionOfTeam ofTeam = new CompetitionOfTeam();
ofTeam.setCompetitionId(teamGroup.getCompetitionId());
ofTeam.setCompetitionGroup(teamGroup.getCompetitionGroup());
ofTeam.setIsDeleted(0L);
List<CompetitionOfTeamVo> groupTeamList = competitionOfTeamMapper.selectCompetitionOfTeamList(ofTeam);
//todo 对球队做循环赛算法
if(groupTeamList.size()>0) {
List<CompetitionTeamVsTeam> allList = new ArrayList<>();
List<BegerArrangementVo> vsListVo = BegerSingleCycleUtil.begerSingleCycle(groupTeamList);
for (BegerArrangementVo vo:vsListVo){
List<CompetitionTeamVsTeam> vsTeams = vo.getVsTeamList();
calendar.add(Calendar.DATE,1);
for(CompetitionTeamVsTeam teamVsTeam:vsTeams){
teamVsTeam.setCompetitionTime(calendar.getTime());
competitionTeamVsTeamMapper.insertCompetitionTeamVsTeam(teamVsTeam);
}
allList.addAll(vsTeams);
}
//System.out.println(JSON.toJSONString(allList));
if(allList.size()>0) {
//todo 如果status = 1 表示 分组内的赛程重新编排,需要删除原来的
if(!StringUtils.isEmpty(competitionTeamGroup.getStatus())){
if(competitionTeamGroup.getStatus().intValue() == 1 ){
CompetitionTeamVsTeam competitionTeamVsTeam = new CompetitionTeamVsTeam();
competitionTeamVsTeam.setCompetitionId(teamGroup.getCompetitionId());
competitionTeamVsTeam.setCompetitionGroup(teamGroup.getCompetitionGroup());
competitionTeamVsTeam.setVsType("循环赛");
competitionTeamVsTeamMapper.updateCompetitionTeamVsTeamByCondition(competitionTeamVsTeam);
}
}
}
CompetitionTeamGroup teamGroup2 = new CompetitionTeamGroup();
teamGroup2.setId(teamGroup.getId());
teamGroup2.setIsCycle(1L);
competitionTeamGroupMapper.updateCompetitionTeamGroup(teamGroup2);
}else {
throw new ServiceException("当前分组中暂无球队数据");
}
redisService.setCacheObject(CacheConstants.ARRANGE_TEAM_GROUP_SCHEDULE+competitionTeamGroup.getId(),true,10L, TimeUnit.SECONDS);
}
return Boolean.TRUE;
}
}

@ -0,0 +1,281 @@
package com.ruoyi.system.utils;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.system.domain.CompetitionOfTeam;
import com.ruoyi.system.domain.CompetitionTeamVsTeam;
import com.ruoyi.system.domain.vo.BegerArrangementVo;
import com.ruoyi.system.domain.vo.CompetitionOfTeamVo;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* "贝格尔"
*/
public class BegerSingleCycleUtil {
/**
* "贝格尔"
*/
public void begerSingleCycle1(int team_Num){
// int team_Num;//队伍的数量
int team_Arr[];//队伍数组
int team_temp[];
boolean empty=false;//是否有轮空
int jump;//调动幅度
int round;//比赛轮数
int flag;//标志队伍的最大的或者0其他队伍在移动的时候如果碰到他将跳过
int tempNum,tempNum1;//队伍在迭代时候保存临时变量的东西
//--------------------初始化一些数据
// Scanner cin = new Scanner(System.in);
System.out.print("输入队伍的数量: "+team_Num);
// team_Num = cin.nextInt();
if(team_Num%2 != 0)//队伍个数为奇数时
{
empty = true;
team_Num++;
}
round = team_Num-1;
jump = ((team_Num+1)/2)-1;
team_Arr = new int[team_Num];
team_temp = new int[team_Num];
for(int i = 0;i< team_Num;i++){
team_Arr[i] = i+1;
}
if(empty)
{
team_Arr[team_Num-1]=0;
}
flag = team_Num-1;
//---------------------开始计算了--------------
for(int j = 0;j< round;j++)
{
System.out.println("第"+(j+1)+"轮:");
for(int m = 0;m< team_Num/2;m++)
{
System.out.println(team_Arr[m]+"----"+team_Arr[team_Num-m-1]);
}
for(int g = 0;g< team_Num;g++)
{
team_temp[g] = team_Arr[g];
}
if(flag != 0 )
{
tempNum = team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
flag = 0;//flag 跳动
tempNum1 = team_Arr[flag];
team_Arr[flag] = tempNum;
}
else
{
tempNum =team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
tempNum1 = team_Arr[team_Num-1];
flag = team_Num-1;//flag 跳动
team_Arr[flag]= team_temp[flag] = tempNum;
team_Arr[0]=team_temp[0] = tempNum1;
}
for(int k = 0;k< team_Num-1;k++)//走动
{
int t = k;
if(t >= team_Num)
t = t - team_Num;
int z = t;
for(int u = 0;u< jump;u++)
{
t++;
if(t == team_Num)
t = t - team_Num;
if(t == flag)
t++;
if(t == team_Num)
t = t-team_Num;
}
team_Arr[t] = team_temp[z];//
}
}
}
/**
* "贝格尔"
*/
public static List<BegerArrangementVo> begerSingleCycle(List<CompetitionOfTeamVo> teamList){
Date date = new Date();
//获取批次号
String batchNumber = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
//遍历一遍方map 里面
Map<Integer,CompetitionOfTeam> teamMap = new HashMap();
Integer numbers = 0;
for (CompetitionOfTeamVo t:teamList) {
numbers++;
//System.out.println(numbers);
teamMap.put(numbers,t);
}
List<BegerArrangementVo> begerArrangementVos = new ArrayList<>();
// int team_Num;//队伍的数量
int team_Arr[];//队伍数组
int team_temp[];
boolean empty=false;//是否有轮空
int jump;//调动幅度
int round;//比赛轮数
int flag;//标志队伍的最大的或者0其他队伍在移动的时候如果碰到他将跳过
int tempNum,tempNum1;//队伍在迭代时候保存临时变量的东西
//--------------------初始化一些数据
// Scanner cin = new Scanner(System.in);
// System.out.print("输入队伍的数量: "+teamList.size());
int team_Num = teamList.size();
// team_Num = cin.nextInt();
if(team_Num %2 != 0)//队伍个数为奇数时
{
empty = true;
team_Num++;
}
round = team_Num-1;
jump = ((team_Num+1)/2)-1;
team_Arr = new int[team_Num];
team_temp = new int[team_Num];
for(int i = 0;i< team_Num;i++){
team_Arr[i] = i+1;
}
if(empty)
{
team_Arr[team_Num-1]=0;
}
flag = team_Num-1;
//---------------------开始计算了--------------
for(int j = 0;j< round;j++)
{
BegerArrangementVo vo = new BegerArrangementVo();
vo.setRound(j+1);
System.out.println("第"+(j+1)+"轮:");
List<CompetitionTeamVsTeam> vsTeamList = new ArrayList<>();
for(int m = 0;m< team_Num/2;m++)
{
CompetitionTeamVsTeam vs = new CompetitionTeamVsTeam();
System.out.println(team_Arr[m]+"----"+team_Arr[team_Num-m-1]);
int mainIdx = team_Arr[m];
int guestIdx = team_Arr[team_Num-m-1];
//todo "0" 表示 轮空;不计入赛程
if(mainIdx>0&&guestIdx>0) {
CompetitionOfTeam mainTeam = teamMap.get(mainIdx);
CompetitionOfTeam guestTeam = teamMap.get(guestIdx);
if (StringUtils.isEmpty(mainTeam)) {
throw new ServiceException("球队分组数据的序号{}有误,匹配失败", mainIdx);
}
if (StringUtils.isEmpty(guestTeam)) {
throw new ServiceException("球队分组数据的序号{}有误,匹配失败", guestIdx);
}
//设置球队值
vs.setMainTeamName(mainTeam.getTeamName());
vs.setMainTeamId(mainTeam.getTeamId());
vs.setGuestTeamId(guestTeam.getTeamId());
vs.setGuestTeamName(guestTeam.getTeamName());
vs.setVsType("循环赛");
vs.setCompetitionId(mainTeam.getCompetitionId());
vs.setCompetitionGroup(mainTeam.getCompetitionGroup());
vs.setBatchNumber(batchNumber);
vsTeamList.add(vs);
}
}
vo.setVsTeamList(vsTeamList);
begerArrangementVos.add(vo);
for(int g = 0;g< team_Num;g++)
{
team_temp[g] = team_Arr[g];
}
if(flag != 0 )
{
tempNum = team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
flag = 0;//flag 跳动
tempNum1 = team_Arr[flag];
team_Arr[flag] = tempNum;
}
else
{
tempNum =team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
tempNum1 = team_Arr[team_Num-1];
flag = team_Num-1;//flag 跳动
team_Arr[flag]= team_temp[flag] = tempNum;
team_Arr[0]=team_temp[0] = tempNum1;
}
for(int k = 0;k< team_Num-1;k++)//走动
{
int t = k;
if(t >= team_Num)
t = t - team_Num;
int z = t;
for(int u = 0;u< jump;u++)
{
t++;
if(t == team_Num)
t = t - team_Num;
if(t == flag)
t++;
if(t == team_Num)
t = t-team_Num;
}
team_Arr[t] = team_temp[z];//
}
}
return begerArrangementVos;
}
/**
*
* @param team_Num
*/
public void begerSimplifySingleCycle(int team_Num){
int n,m;
System.out.print("输入队伍的数量: "+team_Num);
n= team_Num;
if(n%2==0) m=n;
else m=n+1;
int a=1,b=1,index=1,loop=0;
for(int i=1; i<=(m-1)*(m/2); i++)
{
if(a>=m) a=1;
if(index>m/2) index=1;
if(index==1){
loop++;
if(i==1){
b=m;
}else{
b=a;
}
System.out.println("第"+loop+"轮");;
if(((i-1)/(m/2))%2==0){
System.out.println(a+"--"+m);
}else{
System.out.println(m+"--"+a);
}
}else if(index>1 && index<=m/2){
if(b>1) b--;
else b=m-1;
System.out.println(a+"--"+b);
}
index++;
a++;
}
}
public static void main(String args[]){
BegerSingleCycleUtil util= new BegerSingleCycleUtil();
// util.begerSingleCycle(4);
// util.begerSimplifySingleCycle(4);
}
}

@ -144,6 +144,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
where id = #{id}
</update>
<update id="updateCompetitionTeamVsTeamByCondition">
update competition_team_vs_team set is_deleted = 1
<where>
<if test="competitionId != null "> and competition_id = #{competitionId}</if>
<if test="mainTeamId != null "> and main_team_id = #{mainTeamId}</if>
<if test="mainTeamName != null and mainTeamName != ''"> and main_team_name like concat('%', #{mainTeamName}, '%')</if>
<if test="guestTeamId != null "> and guest_team_id = #{guestTeamId}</if>
<if test="guestTeamName != null and guestTeamName != ''"> and guest_team_name like concat('%', #{guestTeamName}, '%')</if>
<if test="competitionTime != null "> and competition_time = #{competitionTime}</if>
<if test="buildingId != null "> and building_id = #{buildingId}</if>
<if test="buildingName != null and buildingName != ''"> and building_name like concat('%', #{buildingName}, '%')</if>
<if test="competitionAddress != null and competitionAddress != ''"> and competition_address = #{competitionAddress}</if>
<if test="competitionGroup != null and competitionGroup != ''"> and competition_group = #{competitionGroup}</if>
<if test="status != null "> and status = #{status}</if>
<if test="lastUpdatedTime != null "> and last_updated_time = #{lastUpdatedTime}</if>
<if test="vsType != null and vsType != ''"> and vs_type = #{vsType}</if>
<if test="batchNumber != null and batchNumber != ''"> and batch_number = #{batchNumber}</if>
</where>
</update>
<delete id="deleteCompetitionTeamVsTeamById" parameterType="Long">
delete from competition_team_vs_team where id = #{id}
@ -155,4 +174,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{id}
</foreach>
</delete>
</mapper>

@ -25,6 +25,15 @@ export function addCompetitionTeamGroup(data) {
data: data
})
}
// 赛会中-分组下一键自动排循环赛
export function arrangeTeamGroupSchedule(data) {
return request({
url: '/system/competitionTeamGroup/arrangeTeamGroupSchedule',
method: 'post',
data: data
})
}
// 修改赛会中-分组
export function updateCompetitionTeamGroup(data) {

@ -57,6 +57,11 @@
max-height="800"
v-loading="loading" :data="competitionOfTeamList" @selection-change="handleSelectionChange">
<el-table-column label="球队ID" align="center" prop="teamId" />
<el-table-column label="球队logo" align="center" prop="avatar" >
<template slot-scope="scope">
<el-avatar :src="scope.row.teamLogo"></el-avatar>
</template>
</el-table-column>
<el-table-column label="球队名" align="center" prop="teamName" />
<el-table-column label="球队所属的组" align="center" prop="competitionGroup" />
<el-table-column label="创建时间" align="center" prop="createdTime" width="180">
@ -148,6 +153,11 @@
<el-main>
<el-table :data="alreadyGroupTeamList">
<el-table-column label="球队ID" align="center" prop="teamId" />
<el-table-column label="球队logo" align="center" prop="avatar" >
<template slot-scope="scope">
<el-avatar :src="scope.row.teamLogo"></el-avatar>
</template>
</el-table-column>
<el-table-column label="球队名" align="center" prop="teamName" />
<el-table-column label="球队所属的组" align="center" prop="competitionGroup" />
<el-table-column label="创建时间" align="center" prop="createdTime" width="180">
@ -417,7 +427,7 @@
import { listCompetition, getCompetition, delCompetition, addCompetition, updateCompetition } from "@/api/system/competition";
import { listCompetitionOfTeam, batchEditById, intoTeamGroup, removeTeamGroup, updateCompetitionOfTeam } from "@/api/system/competitionOfTeam";
import { listCompetitionMembers, getCompetitionMembers, delCompetitionMembers, addCompetitionMembers, updateCompetitionMembers } from "@/api/system/competitionMembers";
import { listCompetitionTeamGroup, getCompetitionTeamGroup, delCompetitionTeamGroup, addCompetitionTeamGroup, updateCompetitionTeamGroup } from "@/api/system/competitionTeamGroup";
import { listCompetitionTeamGroup, arrangeTeamGroupSchedule, delCompetitionTeamGroup, addCompetitionTeamGroup, updateCompetitionTeamGroup } from "@/api/system/competitionTeamGroup";
import { listCompetitionTeamVsTeam, getCompetitionTeamVsTeam, delCompetitionTeamVsTeam, addCompetitionTeamVsTeam, updateCompetitionTeamVsTeam } from "@/api/system/competitionTeamVsTeam";
import { listWxBuilding, getWxBuilding, delWxBuilding, addWxBuilding, updateWxBuilding } from "@/api/system/WxBuilding";
@ -740,7 +750,7 @@ export default {
this.vsTitle = "新增赛程"
},
handleMindTeamVsTeam(){
/*arrangeTeamGroupSchedule({})*/
},
changeMainTeamName(val){
let obj={}

Loading…
Cancel
Save