Commit f7760bb4 authored by 月兔回旋于空中's avatar 月兔回旋于空中

结构 >> 基本结构

parent ff7279cf
Pipeline #11465 passed with stages
in 3 minutes and 3 seconds
......@@ -65,6 +65,11 @@ dependencies {
// ----- 单元测试框架 junit
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
// ----- json序列化工具
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.80'
}
tasks.named('test') {
......
......@@ -7,6 +7,7 @@ import moe.mycard.tabulator.model.dto.GlobalAskBody;
import moe.mycard.tabulator.model.dto.ReturnMessage;
import moe.mycard.tabulator.model.po.TournamentPO;
import moe.mycard.tabulator.model.vo.req.SaveTournamentReq;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateTournamentReq;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -32,15 +33,15 @@ public interface IndexApi {
@ApiOperation("删除 - 单场次比赛")
@PostMapping("/delete_tournament")
ReturnMessage<Void> delete_tournament(@RequestBody GlobalAskBody<Integer> body);
ReturnMessage<Void> delete_tournament(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("详情 - 单场次比赛信息")
@PostMapping("/details_tournament_info")
ReturnMessage<Void> details_tournament_info(@RequestBody GlobalAskBody<Integer> body);
ReturnMessage<TournamentPO> details_tournament_info(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("导出比赛")
@PostMapping("/export_tournament")
ReturnMessage<Void> export_tournament(@RequestBody GlobalAskBody<Integer> body);
ReturnMessage<Void> export_tournament(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("比赛授权")
@PostMapping("/authorize")
......
package moe.mycard.tabulator.api;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import moe.mycard.tabulator.model.dto.GlobalAskBody;
import moe.mycard.tabulator.model.dto.ReturnMessage;
import moe.mycard.tabulator.model.dto.tournament.TTree;
import moe.mycard.tabulator.model.po.TournamentPO;
import moe.mycard.tabulator.model.vo.req.ImportParticipantPO;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateSeatNode;
import moe.mycard.tabulator.model.vo.req.UpdateTournamentReq;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -15,39 +21,49 @@ public interface TournamentApi {
String api = ApiEnum.api + "/tournament";
@ApiOperation("编辑 - 导入参赛信息")
@PostMapping("/edit_import_participant")
ReturnMessage<Integer> edit_import_participant(
@RequestBody GlobalAskBody<ImportParticipantPO> body);
@ApiOperation("制表")
@PostMapping("tabulation")
@ApiImplicitParam(name = "比赛id")
ReturnMessage<TTree> tabulation(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("编辑 - 单场次比赛信息")
@PostMapping("/edit_tournament")
ReturnMessage<Void> edit_tournament(@RequestBody GlobalAskBody<?> body);
ReturnMessage<Void> edit_tournament(@RequestBody GlobalAskBody<UpdateTournamentReq> body);
@ApiOperation("详情 - 单场次比赛信息 常规信息")
@PostMapping("/details_tournament_info")
ReturnMessage<Void> details_tournament_info(@RequestBody GlobalAskBody<Long> body);
ReturnMessage<TournamentPO> details_tournament_info(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("详情 - 单场次比赛信息 树形对战信息")
@PostMapping("/details_tournament_tree")
ReturnMessage<Void> details_tournament_tree(@RequestBody GlobalAskBody<Long> body);
@ApiOperation("编辑 - 对局信息")
@PostMapping("/edit_match")
ReturnMessage<Void> edit_match(@RequestBody GlobalAskBody<?> body);
ReturnMessage<String> details_tournament_tree(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("编辑 - 座位信息")
@PostMapping("/edit_seat")
ReturnMessage<Void> edit_seat(@RequestBody GlobalAskBody<?> body);
ReturnMessage<Void> edit_seat(@RequestBody GlobalAskBody<UpdateSeatNode> body);
@ApiOperation("晋级")
@PostMapping("/promotion")
ReturnMessage<Void> promotion(@RequestBody GlobalAskBody<TidReq> body);
@ApiOperation("分页 - 参赛者对战记录")
@PostMapping("/page_match_record")
ReturnMessage<Page<?>> page_participant_record(@RequestBody GlobalAskBody<?> body);
// @ApiOperation("分页 - 参赛者对战记录")
// @PostMapping("/page_match_record")
// ReturnMessage<Page<?>> page_participant_record(@RequestBody GlobalAskBody<?> body);
@ApiOperation("导出比赛")
@PostMapping("/export_tournament")
ReturnMessage<Void> export_tournament(@RequestBody GlobalAskBody<Long> body);
// @ApiOperation("导出比赛")
// @PostMapping("/export_tournament")
// ReturnMessage<TTree> export_tournament(@RequestBody GlobalAskBody<Integer> body);
@ApiOperation("导出比赛 - 单轮次")
@PostMapping("/export_round")
ReturnMessage<Void> export_round(@RequestBody GlobalAskBody<?> body);
// @ApiOperation("导出比赛 - 单轮次")
// @PostMapping("/export_round")
// ReturnMessage<Void> export_round(@RequestBody GlobalAskBody<?> body);
@ApiOperation("导入比赛 - 单轮次")
@PostMapping("/import_round")
ReturnMessage<Void> import_round(@RequestBody GlobalAskBody<?> body);
// @ApiOperation("导入比赛 - 单轮次")
// @PostMapping("/import_round")
// ReturnMessage<Void> import_round(@RequestBody GlobalAskBody<?> body);
}
......@@ -6,8 +6,10 @@ import moe.mycard.tabulator.api.IndexApi;
import moe.mycard.tabulator.model.dto.GlobalAskBody;
import moe.mycard.tabulator.model.dto.ReturnMessage;
import moe.mycard.tabulator.model.po.TournamentPO;
import moe.mycard.tabulator.model.service.ds.IndexService;
import moe.mycard.tabulator.model.service.ds.IndexDoService;
import moe.mycard.tabulator.model.service.ds.TournamentDoService;
import moe.mycard.tabulator.model.vo.req.SaveTournamentReq;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateTournamentReq;
import org.springframework.web.bind.annotation.RestController;
......@@ -16,7 +18,9 @@ import javax.annotation.Resource;
@RestController
public class IndexDo implements IndexApi {
@Resource private IndexService indexService;
@Resource private IndexDoService indexService;
@Resource private TournamentDoService tournamentDoService;
@Override
public ReturnMessage<Void> save_tournament(GlobalAskBody<SaveTournamentReq> body) {
......@@ -37,18 +41,19 @@ public class IndexDo implements IndexApi {
}
@Override
public ReturnMessage<Void> delete_tournament(GlobalAskBody<Integer> body) {
public ReturnMessage<Void> delete_tournament(GlobalAskBody<TidReq> body) {
indexService.deleteTournament(body);
return ReturnMessage.ok();
}
@Override
public ReturnMessage<Void> details_tournament_info(GlobalAskBody<Integer> body) {
return null;
public ReturnMessage<TournamentPO> details_tournament_info(GlobalAskBody<TidReq> body) {
val data = tournamentDoService.tournamentInfo(body);
return ReturnMessage.data(data);
}
@Override
public ReturnMessage<Void> export_tournament(GlobalAskBody<Integer> body) {
public ReturnMessage<Void> export_tournament(GlobalAskBody<TidReq> body) {
return null;
}
......
package moe.mycard.tabulator.controllers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.val;
import moe.mycard.tabulator.api.TournamentApi;
import moe.mycard.tabulator.model.dto.GlobalAskBody;
import moe.mycard.tabulator.model.dto.ReturnMessage;
import moe.mycard.tabulator.model.dto.tournament.TTree;
import moe.mycard.tabulator.model.po.TournamentPO;
import moe.mycard.tabulator.model.service.ds.IndexDoService;
import moe.mycard.tabulator.model.service.ds.TournamentDoService;
import moe.mycard.tabulator.model.vo.req.ImportParticipantPO;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateSeatNode;
import moe.mycard.tabulator.model.vo.req.UpdateTournamentReq;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class TournamentDo implements TournamentApi {
@Override
public ReturnMessage<Void> edit_tournament(GlobalAskBody<?> body) {
return null;
}
@Override
public ReturnMessage<Void> details_tournament_info(GlobalAskBody<Long> body) {
return null;
}
@Resource private TournamentDoService tournamentDoService;
@Resource private IndexDoService indexDoService;
@Override
public ReturnMessage<Void> details_tournament_tree(GlobalAskBody<Long> body) {
return null;
public ReturnMessage<Integer> edit_import_participant(GlobalAskBody<ImportParticipantPO> body) {
val count = tournamentDoService.importParticipant(body);
return ReturnMessage.data(count);
}
@Override
public ReturnMessage<Void> edit_match(GlobalAskBody<?> body) {
return null;
public ReturnMessage<TTree> tabulation(GlobalAskBody<TidReq> body) {
val table = tournamentDoService.tabulation(body);
return ReturnMessage.data(table);
}
@Override
public ReturnMessage<Void> edit_seat(GlobalAskBody<?> body) {
return null;
public ReturnMessage<Void> edit_tournament(GlobalAskBody<UpdateTournamentReq> body) {
indexDoService.editTournament(body);
return ReturnMessage.ok();
}
@Override
public ReturnMessage<Page<?>> page_participant_record(GlobalAskBody<?> body) {
return null;
public ReturnMessage<TournamentPO> details_tournament_info(GlobalAskBody<TidReq> body) {
val data = tournamentDoService.tournamentInfo(body);
return ReturnMessage.data(data);
}
@Override
public ReturnMessage<Void> export_tournament(GlobalAskBody<Long> body) {
return null;
public ReturnMessage<String> details_tournament_tree(GlobalAskBody<TidReq> body) {
val data = tournamentDoService.tournamentInfo(body);
return ReturnMessage.data(data == null ? null : data.getTournamentSeat());
}
@Override
public ReturnMessage<Void> export_round(GlobalAskBody<?> body) {
return null;
public ReturnMessage<Void> edit_seat(GlobalAskBody<UpdateSeatNode> body) {
tournamentDoService.editSeat(body);
return ReturnMessage.ok();
}
@Override
public ReturnMessage<Void> import_round(GlobalAskBody<?> body) {
public ReturnMessage<Void> promotion(GlobalAskBody<TidReq> body) {
return null;
}
// @Override
// public ReturnMessage<Page<?>> page_participant_record(GlobalAskBody<?> body) {
// return null;
// }
// @Override
// public ReturnMessage<TTree> export_tournament(GlobalAskBody<Integer> body) {
// return null;
// }
// @Override
// public ReturnMessage<Void> export_round(GlobalAskBody<?> body) {
// return null;
// }
//
// @Override
// public ReturnMessage<Void> import_round(GlobalAskBody<?> body) {
// return null;
// }
}
package moe.mycard.tabulator.exception;
import moe.mycard.tabulator.model.dto.GlobalAskBody;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
/** 异常检查器 */
public class CavCore {
......@@ -88,4 +91,24 @@ public class CavCore {
public <object> void cnn(object t, String message) throws CavException {
if (t != null) throw CavException.cast(message);
}
/**
* 错误校验 集合判空形(cn -> check null)
*
* @throws CavException 空异常,携带输入的异常信息
* @see #cn(Object, String)
*/
public void cnList(Collection<?> collection) throws CavException {
if (CollectionUtils.isEmpty(collection)) throw CavException.cast("参数为空");
}
/**
* 错误校验 集合判空形(cn -> check null)
*
* @throws CavException 空异常,携带输入的异常信息
* @see #cn(Object, String)
*/
public void cnList(Collection<?> collection, String message) throws CavException {
if (CollectionUtils.isEmpty(collection)) throw CavException.cast(message);
}
}
package moe.mycard.tabulator.model.dto.tournament;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/** 对局树 */
@Data
public class RTree {
@ApiModelProperty("轮次")
private Integer round;
@ApiModelProperty("桌树")
private SeatNode seatNode;
@ApiModelProperty("当前轮次座位集合")
private List<Integer> seatIdList;
}
package moe.mycard.tabulator.model.dto.tournament;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class SeatData {
@ApiModelProperty("座位id")
private Integer seatId;
@ApiModelProperty("参赛者主键id")
private Integer participantId;
@ApiModelProperty("卡组名称")
private String deck;
@ApiModelProperty("是否锁定")
private Boolean lock;
@ApiModelProperty("对局类型【0 准备阶段】【1 已结束对局】")
private Integer matchType;
@ApiModelProperty("数据类型【1 初始化数据 or 导入数据】【2 系统推算数据】【3 人为编辑数据】")
private Integer dataType;
@ApiModelProperty("时间 - 创建时间")
private LocalDateTime timeCreate;
@ApiModelProperty("时间 - 座位对局时间")
private LocalDateTime timeMatch;
@ApiModelProperty("对局比分")
private Integer matchFraction;
@ApiModelProperty("对局备注")
private String matchRemark;
@ApiModelProperty("对局id")
private Integer matchId;
}
package moe.mycard.tabulator.model.dto.tournament;
public class SeatNode {}
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class SeatNode {
@ApiModelProperty("座位id")
private Integer seatId;
@ApiModelProperty("主要数据")
private SeatData data;
@ApiModelProperty("下一组节点")
private SeatNode[] next;
@ApiModelProperty("上一组节点")
private SeatNode[] previous;
@ApiModelProperty("树深(从1开始)")
private Integer depth;
@ApiModelProperty("树深(从1开始) 倒叙")
private Integer depthDesc;
/**
* 快速创建轮空位
*
* @param seatId 座位id
* @param type 节点类型
* @param depth 树深
* @param depthDesc 树深倒叙
* @param date 创建时间
* @return 轮空位置
*/
public static SeatNode vacancy(
int seatId, int type, int depth, int depthDesc, LocalDateTime date) {
SeatData nodeData = new SeatData();
nodeData.setSeatId(seatId);
nodeData.setParticipantId(null);
nodeData.setDeck("轮空");
nodeData.setLock(false);
nodeData.setMatchType(0);
nodeData.setDataType(2);
nodeData.setTimeCreate(date);
nodeData.setTimeMatch(null);
SeatNode node = new SeatNode();
node.setSeatId(nodeData.getSeatId());
node.setData(nodeData);
node.setNext(null);
node.setPrevious(null);
node.setDepth(depth);
node.setDepthDesc(depthDesc);
return node;
}
public static SeatNode emptySeat(
int seatId, int depth, int depthDesc, LocalDateTime date, SeatNode[] pre) {
SeatData nodeData = new SeatData();
nodeData.setSeatId(seatId);
nodeData.setParticipantId(null);
nodeData.setDeck("");
nodeData.setLock(false);
nodeData.setMatchType(0);
nodeData.setDataType(1);
nodeData.setTimeCreate(date);
nodeData.setTimeMatch(null);
SeatNode node = new SeatNode();
node.setSeatId(nodeData.getSeatId());
node.setData(nodeData);
node.setNext(null);
node.setPrevious(pre);
node.setDepth(depth);
node.setDepthDesc(depthDesc);
return node;
}
}
......@@ -5,95 +5,43 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 主表 - 参赛者
* </p>
*
* @author SPiCa
* @since 2022-03-23
*/
@Data
@TableName("ta_participant")
@ApiModel(value = "Participant对象", description = "主表 - 参赛者")
public class ParticipantPO implements Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
@ApiModelProperty("参赛者 - 主键")
@TableId(value = "participant_id", type = IdType.AUTO)
private Integer participantId;
@ApiModelProperty("参赛者 - 主键")
@TableId(value = "participant_id", type = IdType.AUTO)
private Integer participantId;
@ApiModelProperty("参赛者 - 参赛昵称")
private String participantName;
@ApiModelProperty("参赛者 - 参赛昵称")
private String participantName;
@ApiModelProperty("参赛者 - 参赛卡组")
private String participantDeck;
@ApiModelProperty("参赛者 - 参赛QQ")
private String participantQQ;
@ApiModelProperty("外键 >> 比赛 - 主键id")
private Integer competitionId;
@ApiModelProperty("参赛者 - 参赛卡组")
private String participantDeck;
@ApiModelProperty("时间 - 创建时间")
private LocalDateTime timeCreate;
@ApiModelProperty("外键 >> 比赛 - 主键id")
private Integer tournamentId;
@ApiModelProperty("是否有效 1是 0否")
private Boolean isValid;
@ApiModelProperty("时间 - 创建时间")
private LocalDateTime timeCreate;
public Integer getParticipantId() {
return participantId;
}
public void setParticipantId(Integer participantId) {
this.participantId = participantId;
}
public String getParticipantName() {
return participantName;
}
public void setParticipantName(String participantName) {
this.participantName = participantName;
}
public String getParticipantDeck() {
return participantDeck;
}
public void setParticipantDeck(String participantDeck) {
this.participantDeck = participantDeck;
}
public Integer getCompetitionId() {
return competitionId;
}
public void setCompetitionId(Integer competitionId) {
this.competitionId = competitionId;
}
public LocalDateTime getTimeCreate() {
return timeCreate;
}
public void setTimeCreate(LocalDateTime timeCreate) {
this.timeCreate = timeCreate;
}
public Boolean getIsValid() {
return isValid;
}
public void setIsValid(Boolean isValid) {
this.isValid = isValid;
}
@Override
public String toString() {
return "Participant{" +
"participantId=" + participantId +
", participantName=" + participantName +
", participantDeck=" + participantDeck +
", competitionId=" + competitionId +
", timeCreate=" + timeCreate +
", isValid=" + isValid +
"}";
}
@ApiModelProperty("是否有效 1是 0否")
private Boolean isValid;
}
......@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
......@@ -15,6 +16,7 @@ import java.time.LocalDateTime;
* @author SPiCa
* @since 2022-03-23
*/
@Data
@TableName("ta_tournament")
@ApiModel(value = "Tournament对象", description = "主表 - 比赛表")
public class TournamentPO implements Serializable {
......@@ -51,110 +53,4 @@ public class TournamentPO implements Serializable {
@ApiModelProperty("是否有效")
private Boolean isValid;
public Integer getTournamentId() {
return tournamentId;
}
public void setTournamentId(Integer tournamentId) {
this.tournamentId = tournamentId;
}
public String getTournamentName() {
return tournamentName;
}
public void setTournamentName(String tournamentName) {
this.tournamentName = tournamentName;
}
public String getTournamentSystem() {
return tournamentSystem;
}
public void setTournamentSystem(String tournamentSystem) {
this.tournamentSystem = tournamentSystem;
}
public String getTournamentTime() {
return tournamentTime;
}
public void setTournamentTime(String tournamentTime) {
this.tournamentTime = tournamentTime;
}
public String getTournamentIntroduction() {
return tournamentIntroduction;
}
public void setTournamentIntroduction(String tournamentIntroduction) {
this.tournamentIntroduction = tournamentIntroduction;
}
public String getTournamentSeat() {
return tournamentSeat;
}
public void setTournamentSeat(String tournamentSeat) {
this.tournamentSeat = tournamentSeat;
}
public Integer getTournamentRound() {
return tournamentRound;
}
public void setTournamentRound(Integer tournamentRound) {
this.tournamentRound = tournamentRound;
}
public LocalDateTime getTimeCreate() {
return timeCreate;
}
public void setTimeCreate(LocalDateTime timeCreate) {
this.timeCreate = timeCreate;
}
public LocalDateTime getTimeUpdate() {
return timeUpdate;
}
public void setTimeUpdate(LocalDateTime timeUpdate) {
this.timeUpdate = timeUpdate;
}
public Boolean getIsValid() {
return isValid;
}
public void setIsValid(Boolean isValid) {
this.isValid = isValid;
}
@Override
public String toString() {
return "Tournament{"
+ "tournamentId="
+ tournamentId
+ ", tournamentName="
+ tournamentName
+ ", tournamentSystem="
+ tournamentSystem
+ ", tournamentTime="
+ tournamentTime
+ ", tournamentIntroduction="
+ tournamentIntroduction
+ ", tournamentSeat="
+ tournamentSeat
+ ", tournamentRound="
+ tournamentRound
+ ", timeCreate="
+ timeCreate
+ ", timeUpdate="
+ timeUpdate
+ ", isValid="
+ isValid
+ "}";
}
}
......@@ -12,6 +12,7 @@ import moe.mycard.tabulator.model.service.ILogService;
import moe.mycard.tabulator.model.service.ITournamentAssignService;
import moe.mycard.tabulator.model.service.ITournamentService;
import moe.mycard.tabulator.model.vo.req.SaveTournamentReq;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateTournamentReq;
import moe.mycard.tabulator.tool.UtilTime;
import org.springframework.beans.BeanUtils;
......@@ -20,9 +21,10 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class IndexService {
public class IndexDoService {
private final CavCore c = CavCore.getC();
@Resource private ITournamentService tournamentService;
@Resource private ITournamentAssignService tournamentAssignService;
@Resource private ILogService logService;
......@@ -50,6 +52,11 @@ public class IndexService {
return page;
}
/**
* 生成比赛信息
*
* @param body saveReq
*/
public void saveTournament(GlobalAskBody<SaveTournamentReq> body) {
c.cn(body);
// ===== 主逻辑,生成比赛 =====
......@@ -67,6 +74,11 @@ public class IndexService {
logService.create(UserInfo.getUserId(), "创建了比赛 " + savePO);
}
/**
* 编辑比赛信息
*
* @param body updateReq
*/
public void editTournament(GlobalAskBody<UpdateTournamentReq> body) {
c.cn(body);
val tid = body.getParams().getTournamentId();
......@@ -93,9 +105,14 @@ public class IndexService {
logService.create(userId, "编辑了比赛 " + updatePO);
}
public void deleteTournament(GlobalAskBody<Integer> body) {
/**
* 删除比赛信息
*
* @param body 比赛id
*/
public void deleteTournament(GlobalAskBody<TidReq> body) {
c.cn(body);
val tournamentId = body.getParams();
val tournamentId = body.getParams().getTournamentId();
c.cn(tournamentId, "比赛id为空");
val userId = UserInfo.getUserId();
......
package moe.mycard.tabulator.model.service.ds;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.val;
import moe.mycard.tabulator.exception.CavCore;
import moe.mycard.tabulator.model.dto.GlobalAskBody;
import moe.mycard.tabulator.model.dto.tournament.RTree;
import moe.mycard.tabulator.model.dto.tournament.SeatData;
import moe.mycard.tabulator.model.dto.tournament.SeatNode;
import moe.mycard.tabulator.model.dto.tournament.TTree;
import moe.mycard.tabulator.model.po.ParticipantPO;
import moe.mycard.tabulator.model.po.TournamentPO;
import moe.mycard.tabulator.model.service.IParticipantService;
import moe.mycard.tabulator.model.service.ITournamentService;
import moe.mycard.tabulator.model.vo.req.ImportParticipantPO;
import moe.mycard.tabulator.model.vo.req.TidReq;
import moe.mycard.tabulator.model.vo.req.UpdateSeatNode;
import moe.mycard.tabulator.tool.UtilTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class TournamentDoService {
private static final Map<Integer, TTree> tidMapTree = new HashMap<>();
private static final Map<Integer, Map<Integer, SeatNode>> tidMapSeatIdMapNode = new HashMap<>();
private final CavCore c = CavCore.getC();
@Resource private IParticipantService participantService;
@Resource private ITournamentService tournamentService;
public static void main(String[] args) {
RTree rTree = new RTree();
rTree.setSeatNode(
new SeatNode() {
{
setDepthDesc(1);
}
});
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(rTree);
System.out.println(jsonObject);
}
/**
* 导入参赛者名录
*
* @param body 比赛id and 参赛名录
* @return 参赛者数量
*/
@Transactional(rollbackFor = Exception.class)
public int importParticipant(GlobalAskBody<ImportParticipantPO> body) {
c.cn(body);
val directory = body.getParams().getDirectory();
val tid = body.getParams().getTournamentId();
c.c(StringUtils.isBlank(directory), "空名录");
char[] str = directory.toCharArray();
List<String> participantList = new ArrayList<>();
List<ParticipantPO> participantPOS = new ArrayList<>();
val date = UtilTime.getDateL();
StringBuilder sb = new StringBuilder();
for (var c : str) {
if (c == 10 || c == 13) {
participantList.add(sb.toString());
sb = new StringBuilder();
} else {
sb.append(c);
}
}
participantList.forEach(
deck -> {
val e = deck.split("\\+");
val savePO = new ParticipantPO();
savePO.setParticipantName(e[0]);
savePO.setParticipantQQ(e[1]);
savePO.setParticipantDeck(deck);
savePO.setTournamentId(tid);
savePO.setTimeCreate(date);
savePO.setIsValid(true);
participantPOS.add(savePO);
});
participantService.saveBatch(participantPOS);
return participantPOS.size();
}
/**
* 制表
*
* @param body 比赛id
* @return 表树
*/
public TTree tabulation(GlobalAskBody<TidReq> body) {
c.cn(body);
val tid = body.getParams().getTournamentId();
val participantPOS =
participantService.list(
new LambdaQueryWrapper<ParticipantPO>()
.select(ParticipantPO::getParticipantDeck)
.eq(ParticipantPO::getTournamentId, tid)
.eq(ParticipantPO::getIsValid, true));
Collections.shuffle(participantPOS);
c.cnList(participantPOS, "参赛名录为空");
val tournamentPO = tournamentService.getById(tid);
var id = 1;
var size = participantPOS.size();
val date = UtilTime.getDateL();
Map<Integer, List<Integer>> roundMapSeatArray = new HashMap<>();
if (participantPOS.size() % 2 != 0) {
size = size + 1;
}
val depth = getDepth(size, 0);
SeatNode[] nodes = new SeatNode[size];
for (int i = 0; i < size - 1 - 1; i++) {
val participantPO = participantPOS.get(i);
SeatData nodeData = new SeatData();
roundMapSeatArray.computeIfAbsent(tid, k -> new ArrayList<>());
roundMapSeatArray.get(tid).add(id);
nodeData.setSeatId(id);
nodeData.setParticipantId(participantPO.getParticipantId());
nodeData.setDeck(participantPO.getParticipantDeck());
nodeData.setLock(false);
nodeData.setMatchType(0);
nodeData.setDataType(1);
nodeData.setTimeCreate(date);
nodeData.setTimeMatch(null);
SeatNode node = new SeatNode();
node.setSeatId(nodeData.getSeatId());
node.setData(nodeData);
node.setNext(null);
node.setPrevious(null);
node.setDepth(depth);
node.setDepthDesc(1);
nodes[i] = node;
tidMapSeatIdMapNode.computeIfAbsent(tid, k -> new HashMap<>());
tidMapSeatIdMapNode.get(tid).put(id, node);
id++;
}
nodes[size - 1] = SeatNode.vacancy(id, 2, depth, 1, date);
val seatTree = leafToTree(id, depth, 2, date, nodes, roundMapSeatArray);
List<RTree> rTreeList = new ArrayList<>();
roundMapSeatArray.forEach(
(kev, value) -> {
RTree rTree = new RTree();
rTree.setRound(kev);
rTree.setSeatNode(seatTree);
rTree.setSeatIdList(value);
rTreeList.add(rTree);
});
TTree tTree = new TTree();
tTree.setTournamentSystem(tournamentPO.getTournamentSystem());
tTree.setTournamentId(tid);
tTree.setTournamentName(tournamentPO.getTournamentName());
tTree.setSign("sign");
tTree.setRoundTreeList(rTreeList);
val updatePO = new TournamentPO();
updatePO.setTournamentId(tid);
updatePO.setTimeUpdate(date);
updatePO.setTournamentSeat(((JSONObject) JSONObject.toJSON(tTree)).toString());
updatePO.setTournamentRound(1);
tournamentService.updateById(updatePO);
tidMapTree.put(tid, tTree);
return tTree;
}
/**
* 获取比赛详情
*
* @param body 比赛id
* @return 比赛详情
*/
public TournamentPO tournamentInfo(GlobalAskBody<TidReq> body) {
c.cn(body);
return tournamentService.getById(body.getParams().getTournamentId());
}
/*
======================================================================================================================
*/
/**
* 编辑座位信息
*
* @param body 座位信息
*/
public void editSeat(GlobalAskBody<UpdateSeatNode> body) {
c.cn(body);
val seatNode = body.getParams();
c.cn(seatNode.getTournamentId());
c.cn(seatNode.getSeatId());
val seat = tidMapSeatIdMapNode.get(seatNode.getTournamentId()).get(seatNode.getSeatId());
c.cn(seat);
if (StringUtils.isNotBlank(seatNode.getDeck())) {
seat.getData().setDeck(seatNode.getDeck());
}
if (seatNode.getMatchFraction() != null) {
seat.getData().setMatchFraction(seatNode.getMatchFraction());
}
if (StringUtils.isNotBlank(seatNode.getMatchRemark())) {
seat.getData().setMatchRemark(seatNode.getMatchRemark());
}
}
/**
* 获取树深 64/2 32/2 16/2 8/2 4/2 2/2 1
*
* @param size 参赛总数
*/
private int getDepth(int size, int depth) {
if (size < 2) {
return depth + 1;
} else {
if (size % 2 != 0) {
size = size + 1;
}
return getDepth(size / 2, depth + 1);
}
}
/**
* 叶子推算树
*
* @param id 座位id
* @param depth 树深
* @param depthDesc 树深倒叙
* @param date 创建时间
* @param seatNodes 子叶子
* @param roundMapSeatArray 轮数映射位置集合
* @return 对局树集合
*/
private SeatNode leafToTree(
int id,
int depth,
int depthDesc,
LocalDateTime date,
SeatNode[] seatNodes,
Map<Integer, List<Integer>> roundMapSeatArray) {
boolean combination = true;
List<SeatNode> curList = new ArrayList<>();
// ===== 顶层节点 =====
if (seatNodes.length < 2) {
val curNode = seatNodes[0];
val next = SeatNode.emptySeat(id, depth, depthDesc, date, new SeatNode[] {curNode});
curNode.setNext(new SeatNode[] {next});
return next;
}
// ===== 顶层节点 =====
// ===== 当前节点集合 =====
for (int i = 0; i < seatNodes.length - 1; i++) {
val curNode = seatNodes[i];
SeatNode next;
if (combination) {
next = SeatNode.emptySeat(id++, depth, depthDesc, date, new SeatNode[] {curNode});
curNode.setNext(new SeatNode[] {next});
next.setPrevious(new SeatNode[] {curNode});
} else {
next = seatNodes[i - 1].getNext()[0];
curNode.setNext(new SeatNode[] {next});
next.setPrevious(new SeatNode[] {curNode, next.getPrevious()[0]});
}
curList.add(curNode);
combination = !combination;
}
// ===== 当前节点集合 =====
// ===== 轮空位 =====
if (!combination) {
val next = seatNodes[seatNodes.length - 1].getNext()[0];
val cur = SeatNode.emptySeat(id++, depth, depthDesc, date, null);
cur.setNext(new SeatNode[] {next});
next.setPrevious(new SeatNode[] {cur, next.getPrevious()[0]});
curList.add(cur);
}
// ===== 轮空位 =====
roundMapSeatArray.put(
depthDesc, curList.stream().map(SeatNode::getSeatId).collect(Collectors.toList()));
return leafToTree(
id, depth - 1, depthDesc + 1, date, curList.toArray(new SeatNode[0]), roundMapSeatArray);
}
}
package moe.mycard.tabulator.model.vo.req;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ImportParticipantPO {
@ApiModelProperty("参赛者名录")
private String directory;
@ApiModelProperty("比赛 - 主键id")
private Integer tournamentId;
}
package moe.mycard.tabulator.model.vo.req;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class TidReq {
@ApiModelProperty("比赛id")
private Integer tournamentId;
}
package moe.mycard.tabulator.model.vo.req;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class UpdateSeatNode {
@ApiModelProperty("比赛 - 主键id")
private Integer tournamentId;
@ApiModelProperty("座位id")
private Integer seatId;
@ApiModelProperty("卡组名称")
private String deck;
// @ApiModelProperty("时间 - 座位对局时间")
// private LocalDateTime timeMatch;
@ApiModelProperty("对局比分")
private Integer matchFraction;
@ApiModelProperty("对局备注")
private String matchRemark;
// @ApiModelProperty("对局id")
// private Integer matchId;
}
package moe.mycard.tabulator;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TabulatorApplicationTests {
@Test
void contextLoads() {
}
void contextLoads() {}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment