芝法酱躺平攻略(5)—— SpringBoot编写公主连结公会战报刀工具

一、业务分析

1.1 简化的增删改查业务

本期只先实现业务,还没有涉及鉴权等操作,故用户和公会系统,就简单编写。
用户系统

函数命功能描述
create创建用户传昵称,创建用户
info查看用户传id,返回用户信息
delete删除用户传id,删除用户
edit编辑用户传id,与用户Dto
page查看用户分页传公会Id,用户名。只传公会Id则查公会下的所有用户。传用户名,模糊查找用户
join加入公会传用户Id,公会Id。公会限制30人,满员不能加入。公会战期间不能加入。已加入公会的用户,必须退出公会才能加入其他公会
quit退出公会传用户Id。公会战期间不能退出公会。

公会系统

函数名功能描述
create创建公会传昵称,创建公会
info查看公会传id,返回公会信息
delete删除公会传id,删除公会
edit编辑公会传id,公会Dto
page公会分页可传公会昵称,模糊查找公会
status查看会战状态传id,查看会战的状态,展示公会的出刀数量和单日出刀数量,以及当前BOSS状态

报刀系统
报刀表的创建在Game模块,故该模块只有查找

函数名功能描述
info报刀信息传id,返回信息
listForPlayer查看玩家的出刀传会战Id,玩家Id,战斗日。战斗日传0则按当日计算
page查看刀分页必传会战Id,选传BossId,玩家Id,公会Id

1.2 核心的会战模拟

1.2.1 公主连接公会战介绍

公主连接是2018年在日本大火的一款类dota传奇卡牌游戏。2020年进入国服,深受玩家好评。
其中小编认为最有意思的一个玩法就是公会战系统:
公会人数
在公主连接中,每个公会可以招收30名公会成员。
会战举办
每月会以当月星座为主题,举办公会战。
会战玩什么
所谓公会战,就是公会30人一起打BOSS,看哪个公会打的BOSS多。
每个公会的公会战进度独立,每轮5个BOSS,不同BOSS的强度不同,收到每点伤害所获得的积分也不同。
会战BOSS
打完本轮5个BOSS后会刷新BOSS,进入下一轮。
BOSS战分多个阶段,更高阶段的BOSS强度更高,响应分数也更高。初始时为A阶段,第4轮后进入B阶段,第10轮后进入C阶段。
玩家出刀
会战期间,每位玩家1天有3次挑战BOSS的机会,每次打1分半钟,如果在这刀中击杀BOSS,则会生成一个补偿刀,补偿刀时间根据剩余时间计算。
会战时长与排名
公会战进行6天,结束后统计各公会排名,按排名发放奖励。

1.2.2 公会战涉及的数据库表实体

为了便于讲解,我们先把会战涉及的数据库实体给出:

公会战实体 Battle
逻辑主键:unionId,year,constellation

字段名类型描述
idLong主键
unionIdLong公会Id
yearInteger会战年
constellationEConstellation会战星座
bossIdLong当前存活BOSS的bossId
roundInteger第几周目
bossIdxInteger本周目第几个BOSS

BOSS实体 BossEntity
逻辑索引:battleId(1:n)

字段名类型描述
idLong主键
battleIdLong会战Id
bossTypeEBossTypeboss类型,该枚举存放BOSS的属性积分系数等额外信息
hpInteger剩余血量
aliveBoolean是否存活

刀实体 HitEntity
逻辑索引 userId,bossId
userId,battleId,day,hitIndex

字段名类型描述
idLong主键
userIdLong玩家Id
nickNameString玩家昵称,冗余字段
unionIdLong玩公会Id,冗余字段
battleIdLong会战Id
bossIdLongboss Id
doneBoolean是否出刀
demageInteger伤害
scoreInteger分数
dayInteger第几天的刀
hitIndexInteger当日第几刀,补偿刀和尾刀都算在1刀里
hitTypeEHitType刀类型

玩家每日会战信息 PlayerBattleDayEntity
逻辑索引 playerId,battleId,day

字段名类型描述
idLong主键
userIdLong玩家Id
playerNameString玩家名称,冗余字段
battleIdLong会战Id
dayInteger第几天
hitWholeInteger今日完整刀出刀次数
hitTailInteger今日尾刀次数
hitCompensateInteger今日补偿刀次数

全局游戏变量

字段名类型描述
mBattleOnBoolean是否开启公会战
mYearint会战年
mConstellationEConstellation会战星座
mDayint会战日

1.3 排行榜业务

在会战过程中,需要常常查看公会会战的状态,如当天出了多少刀,打到第几个BOSS,BOSS血量多少等。
玩家也需要实时查询自己在公会中的排名,公会当前的排名,今天出了多少刀等。

1.3.1 排行榜相关实体

玩家分数实体 PlayerScoreEntity
逻辑索引 playerId,battleId

字段名类型描述
playerIdLong玩家Id
playerNameString玩家名称,冗余字段
battleIdLong会战Id
scoreInteger本期会战得分
demageInteger本期会战伤害

玩会战分数实体 UnionScoreEntity
逻辑索引 unionId,battleId

字段名类型描述
unionIdLong公会Id
unionNameString公会名称
battleIdLong会战Id
yearInteger会战年
constellationEConstellation星座
roundInteger第几轮
bossIdxInteger第几个BOSS
scoreInteger分数

1.4 游戏模块业务概述

在整体上理解业务后,我们可以先把业务需求抽象成接口,然后缕清每个接口的流程,最后再构思实现。

1.4.1 IGameService 接口定义

    /**
     * 开启公会战
     *
     * @param pYear             年
     * @param pEConstellation   星座
     * @return
     */
    void startBattle(int pYear, EConstellation pEConstellation);

    /**
     * 使公会战过1天
     *
     * @return
     */
    Integer dayPass();

    /**
     * 某玩家报刀
     *
     * @param   pPlayerId   玩家Id
     * @param   pDamage     伤害
     * @return  HitResultVo  伤害响应
     */
    HitResultVo hit(Long pPlayerId, Integer pDamage);

    /**
     * 某玩家尾刀
     *
     * @param   pPlayerId   玩家Id
     * @return  HitResultVo 伤害响应
     */
    HitResultVo tail(Long pPlayerId);

    /**
     * 查询会战状态
     *
     * @param  pBattleEntity    会战实体
     * @return BattleInfoVo     会战状态
     */
    BattleInfoVo status(BattleEntity pBattleEntity);
    /**
     * 撤回,本期不实现
     *
     * @param  pUnionId  公会Id
     * @return BattleInfoVo 会战信息
     */
    BattleInfoVo withDraw(Long pUnionId);

    /**
     * 获取是公会战第几天
     *
     * @return
     */
    Integer getDay();

    /**
     * 获取当前会战年
     *
     * @return
     */
    Integer getYear();

    /**
     * 获取当前会战星座
     *
     * @return
     */
    EConstellation getConstellation();

    /**
     * 当前是否正在公会战
     *
     * @return
     */
    boolean isBattleOn();
}

1.4.2 启动服务器

由于我们需要一些全局变量,保存当前是否开启了会战,会战年和星座是什么,进行到了第几天。
所以启动服务时需要从数据库同步这些数据。

1.4.3 开启会战

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void startBattle(int pYear, EConstellation pEConstellation) {
        // #1 检测是否已经开启会战,如果开启则报错
        // #2 同步输入的年、星座、会战开启状态到全局变量和数据库
        // #3 遍历所有公会
        List<UnionEntity> unionEntityList = mUnionDbService.list();
        for (UnionEntity unionEntity : unionEntityList){
            // #4 创建会战
            // #5 创建公会分数实体
            // #6 初始化BOSS
            // #7 遍历所有公会成员
            List<UserEntity> userEntityList = mUserDbService.listByUnionId(unionEntity.getId());
            for(UserEntity userEntity : userEntityList){
                for(int day = 1; day <=6; day ++){
                    for(int hitIdx=1;hitIdx<=3;hitIdx++){
                        // #8 创建刀数据,初始状态Done设置为false
                    }
                    // #10 创建玩家每日数据
                }
                // #9 创建玩家分数数据
            }
        }
    }

1.4.4 过1天

    @Override
    public Integer dayPass() {
        // #1 检测是否已经开启会战,如果没开启则报错
        // #2 如果当前天已经是第6天,则结束会战;否则当前天+1
        // #3 同步全局变量
        return mDay;
    }

1.4.5 报刀

在这里插入图片描述

1.4.5 尾刀

在这里插入图片描述

1.4.6 BOSS生成

在正常开发中,BOSS数据应当由策划编写Excel表,而后导出数据,服务端启服读取。
但本篇毕竟是攻略性质,要聚焦核心知识点。
所以小编写了一个枚举,来配置BOSS的属性。

@RequiredArgsConstructor
public enum EBossType {
    BOSS1_P1(101,"龙",7000000,1,1,1.0f),
    BOSS2_P1(102,"鸟",9000000,2,1,1.1f),
    BOSS3_P1(103,"狼",13000000,3,1,1.3f),
    BOSS4_P1(104,"熊",15000000,4,1,1.5f),
    BOSS5_P1(105,"猪",20000000,5,1,1.8f),
    BOSS1_P2(201,"龙",7000000,1,2,1.5f),
    BOSS2_P2(202,"鸟",9000000,2,2,1.6f),
    BOSS3_P2(203,"狼",13000000,3,2,1.8f),
    BOSS4_P2(204,"熊",15000000,4,2,2.0f),
    BOSS5_P2(205,"猪",20000000,5,2,2.5f),
    BOSS1_P3(301,"龙",7000000,1,3,1.8f),
    BOSS2_P3(302,"鸟",9000000,2,3,2.0f),
    BOSS3_P3(303,"狼",13000000,3,3,2.5f),
    BOSS4_P3(304,"熊",15000000,4,3,2.8f),
    BOSS5_P3(305,"猪",20000000,5,3,3.0f);

    @EnumValue
    @Getter
    final Integer code;
    @Getter
    final String name;
    @Getter
    final Integer maxHp;
    @Getter
    final Integer index;
    @Getter
    final Integer phase;
    @Getter
    final Float factor;
}

在生成BOSS时,根据phase,bossIdx生成对用的BOSS

二、用到的实体

为了更好的做接口设计,先把接口用到的实体展示出来

2.1 枚举

2.1.1 BOSSMemo

由于BOSSId不是从1开始连续的,所以做个辅助Memo,方便查找
后面的攻略,会介绍如何写一个通用的枚举Memo,管理项目中所有的枚举,并方便前端做下拉列表。
此处先简单粗暴的对付下:

@Component
public class BossTypeMemo extends HashMap<Integer, EBossType>{
    public BossTypeMemo(){
        for(EBossType bossType : EBossType.values()){
            put(bossType.getCode(),bossType);
        }
    }
}

2.1.2 EBattleStatus

boss的状态

@RequiredArgsConstructor
public enum EBattleStatus {
    ON_GOING(1,"进行中"),
    FINISH(2,"完成");

    @EnumValue
    @Getter
    final Integer code;
    @Getter
    final String name;
}

2.1.3 EConstellation

星座

@RequiredArgsConstructor
public enum EConstellation {
    DEFAULT(0,"未定义"),
    Aquarius(1,"水瓶座"),
    Pisces(2,"双鱼座"),
    Aries(3,"白羊座"),
    Taurus(4,"金牛座"),
    Gemini(5,"双子座"),
    Cancer(6,"巨蟹座"),
    Leo(7,"狮子座"),
    Virgo(8,"处女座"),
    Libra(9,"天秤座"),
    Scorpio(10,"天蝎座"),
    Sagittarius(11,"射手座"),
    Capricorn(12,"摩羯座");
    
    @EnumValue
    @Getter
    final Integer code;
    @Getter
    final String name;
}

2.1.4 EHitType

刀类型

@RequiredArgsConstructor
public enum EHitType {
    WHOLE(1,"完整刀"),
    TAIL(2,"尾刀"),
    COMPENSATE(3,"补偿刀");

    @EnumValue
    @Getter
    final Integer code;
    @Getter
    final String name;
}

2.1.5 EValueType

值类型

@RequiredArgsConstructor
public enum EValueType {
    STRING(1,"字符串"),
    INTEGER(2,"整数"),
    LONG(3,"长整型"),
    DOUBLE(4,"浮点型"),
    BOOLEAN(5,"布尔");

    @EnumValue
    @Getter
    final Integer code;
    @Getter
    final String name;
}

2.1.6 ERankListSort

排序方式

@RequiredArgsConstructor
public enum ERankListSort {

    SCORE(1,"分数"),
    DAMAGE(2,"伤害");

    final int code;
    final String desc;
}

2.2 数据库实体

由于前面已经用表格介绍过,此处会略过大部分实体
本期的数据库实体中,除了UserEntity和UnionEntity继承自BaseEntity外,其他实体全继承自SysBaseEntity
下面仅展示几个有代表醒的

2.2.1 SysDataEntity

系统数据

@TableName("bl_sys_data")
@Data
public class SysDataEntity{

    @Schema(title = "键")
    @TableId(type = IdType.INPUT,value = "`key`")
    protected String key;
    @Schema(title = "字段类型")
    @TableField(value = "`type`")
    protected EValueType type;
    @Schema(title = "值")
    @TableField(value = "`value`")
    protected String value;
    @JSONField(serialize = false, deserialize = false)
    @TableField(fill = FieldFill.INSERT)
    @Schema(title = "创建时间")
    protected LocalDateTime createTime;
    @JSONField(serialize = false, deserialize = false)
    @TableField(fill = FieldFill.UPDATE)
    @Schema(title = "修改时间")
    protected LocalDateTime modifyTime;
    @Schema(title = "版本")
    @Version
    protected Integer version;

    public void createInit() {
        // 靠全局配置填充
        createTime = null;
        modifyTime = null;
        version = 0;
    }

    public void updateInit() {
        modifyTime = null;
    }

    public String stringVal(){
        if(EValueType.STRING != type){
            throw new ServiceException("类型不为字符串");
        }
        return value;
    }

    public Integer intVal(){
        if(EValueType.INTEGER != type){
            throw new ServiceException("类型不为整型");
        }
        return Integer.valueOf(value);
    }

    public Long longVal(){
        if(EValueType.LONG != type){
            throw new ServiceException("类型不为长整型");
        }
        return Long.valueOf(value);
    }

    public Double doubleVal(){
        if(EValueType.DOUBLE != type){
            throw new ServiceException("类型不为浮点");
        }
        return Double.valueOf(value);
    }

    public Boolean booleanVal(){
        if(EValueType.BOOLEAN != type){
            throw new ServiceException("类型不为布尔");
        }
        if("true".equals(value)){
            return true;
        }else if("false".equals(value)){
            return false;
        }
        return null;
    }
}

2.2.2 UnionEntity

公会实体

@Data
@TableName("bl_union")
@Schema(name = "UnionEntity对象", description = "公会表")
public class UnionEntity extends BaseEntity {
    @Schema(title = "昵称")
    private String name;
    @Schema(title = "当前会战Id")
    private Long battleId;
    @TableField(value = "`rank`")
    @Schema(title = "上期排名")
    private Integer rank;
    @Schema(title = "上期会战分数Id")
    private Long scoreId;
}

2.2.3 BattleEntity

会战实体

@Data
@TableName("bl_battle")
@Schema(name = "公会战对象", description = "公会战")
public class BattleEntity extends BaseEntity {
    @Schema(title = "公会的id")
    private Long unionId;
    @Schema(title = "哪一年的公会战")
    private Integer year;
    @Schema(title = "星座")
    private EConstellation constellation;
    @Schema(title = "bossId")
    private Long bossId;
    @Schema(title = "第几周目")
    private Integer round;
    @Schema(title = "第几BOSS")
    private Integer bossIdx;
    @Schema(title = "目前公会战进行了几天")
    private Integer day;
    @Schema(title = "公会战的状态,ON_GOING(1), FINISH(2)")
    private EBattleStatus status;
    
}

2.2.4 BossEntity

boss数据

@Data
@TableName("bl_boss")
@Schema(title = "BossEntity对象", description = "boss类")
public class BossEntity extends SysBaseEntity {
    @Schema(name = "公会战id")
    private Long battleId;
    @Schema(name = "boss类型")
    private EBossType bossType;
    @Schema(name = "剩余血量")
    private Integer hp;
    @Schema(name = "是否存活")
    private Boolean alive;
}

2.2.5 PlayerBattleDayEntity

玩家日数据

@Schema(title = "玩家会战日数据",description = "记录玩家每日会战的情况,出刀次数,是否SL")
@TableName("bl_player_battle_day")
@Data
public class PlayerBattleDayEntity extends SysBaseEntity {
    @Schema(title = "玩家id")
    private Long playerId;
    @Schema(title = "玩家名称")
    private String playerName;
    @Schema(title = "公会战id")
    private Long battleId;
    @Schema(title = "第几天")
    private Integer day;
    @Schema(title = "完整刀次数")
    private Integer hitWhole;
    @Schema(title = "尾刀次数")
    private Integer hitTail;
    @Schema(title = "补偿刀次数")
    private Integer hitCompensate;
    @Schema(title = "是否SL")
    private Boolean sl;
}

2.3 一些查询用到的DTO,VO

2.3.1 创建玩家和公会的dto

@Schema(title = "用户创建请求数据")
@Data
public class UserDto {
    @Schema(title = "昵称")
    private String nickName;
}

@Schema(title = "公会创建请求数据")
@Data
public class UnionDto {
    @Schema(title = "昵称")
    private String name;
}

2.3.2 公会会战状态VO

@Schema(name = "公会战状态")
@Data
public class UnionBattleStatusVo {
    @Schema(name = "公会的id")
    private Long unionId;
    @Schema(name = "公会名称")
    private String unionName;
    @Schema(name = "战斗id")
    Long battleId;
    @Schema(name = "完整刀次数")
    Integer hitWhole;
    @Schema(name = "尾刀次数")
    Integer hitTail;
    @Schema(name = "补偿刀次数")
    Integer hitCompensate;
    @Schema(name = "哪一年的公会战")
    private Integer year;
    @Schema(name = "星座")
    private EConstellation constellation;
    @Schema(name = "第几阶段")
    private Integer phase;
    @Schema(name = "目前公会战进行了几天")
    private Boolean day;
    @Schema(name = "公会战的状态,ON_GOING(1), FINISH(2)")
    private EBattleStatus status;
}

@Schema(name = "刀VO")
@Data
public class HitVo extends HitEntity {
    @Schema(name = "boss名字")
    String bossName;
}

2.3.3 game模块的VO

@Data
public class BattleInfoVo extends BattleEntity {
    @Schema(title = "当前Boss状态")
    BossEntity bossStatus;
    @Schema(title = "完整刀次数")
    int hitWhole;
    @Schema(title = "尾刀次数")
    int hitTail;
    @Schema(title = "补偿刀次数")
    int hitCompensate;

    @Schema(title = "今日完整刀次数")
    int hitWholeDay;
    @Schema(title = "今日尾刀次数")
    int hitTailDay;
    @Schema(title = "今日补偿刀次数")
    int hitCompensateDay;
}

@Data
public class HitResultVo extends HitEntity{
    @Schema(title = "boss 状态")
    BossEntity bossStatus;
}

@Data
public class RankData extends UnionScoreEntity {
    int rank;
}

2.3.4 排行榜模块的VO

@Schema(title = "玩家排名节点信息")
@Data
public class PlayerRankListItemVo {
    @Schema(title = "玩家Id")
    Long playerId;
    @Schema(title = "玩家名字")
    String playerName;
    @Schema(title = "总伤害")
    Integer demage;
    @Schema(title = "总分数")
    Integer score;
}

@Data
@Schema(title = "玩家排名信息")
public class PlayerRankListVo {
    @Schema(title = "公会战Id")
    Long battleId;
    @Schema(title = "公会战年")
    Integer year;
    @Schema(title = "星座")
    EConstellation constellation;
    @Schema(title = "公会Id")
    Long unionId;
    @Schema(title = "公会名称")
    String unionName;
    @Schema(title = "排名数据")
    List<PlayerRankListItemVo> data;
}

@Schema(title = "公会排行榜节点")
@Data
public class UnionRankListItemVo {
    @Schema(title = "公会的id")
    Long unionId;
    @Schema(title = "公会的名字")
    String unionName;
    @Schema(title = "总分数")
    Integer score;
    @Schema(title = "第几轮")
    Integer round;
    @Schema(title = "第几个BOSS")
    Integer bossIdx;
    @Schema(title = "BOSS名称")
    String bossName;
    @Schema(title = "BOSS血量百分比")
    float bossHpPercent;
}

@Data
@Schema(name = "公会排行榜")
public class UnionRankListVo {
    @Schema(name = "公会战年")
    Integer year;
    @Schema(name = "星座")
    EConstellation constellation;
    @Schema(name = "分页数据")
    Page<UnionRankListItemVo> page;
}

三、dao层的一些接口和实现

由于本篇不牵扯对mapper的修改,大部分dbService也没有做什么修改,故只展示已修改的dbService

3.1 UserDbService

public interface IUserDbService extends IZfDbService<UserEntity> {
    /**
     * 查找公会内的所有成员
     *
     * @param pUnionId  公会Id
     * @return
     */
    List<UserEntity> listByUnionId(Long pUnionId);

    /**
     * 看下公会有多少人
     *
     * @param pUnionId  公会Id
     * @return
     */
    int countByUnionId(Long pUnionId);
}

@Service
public class UserDbServiceImpl extends ZfDbServiceImpl<UserMapper, UserEntity> implements IUserDbService {

    @Override
    public List<UserEntity> listByUnionId(Long pUnionId) {
        LambdaQueryWrapper<UserEntity> wrapper = Wrappers.<UserEntity>lambdaQuery()
                .eq(UserEntity::getUnionId,pUnionId);

        return baseMapper.selectList(wrapper);
    }

    @Override
    public int countByUnionId(Long pUnionId) {
        LambdaQueryWrapper<UserEntity> wrapper = Wrappers.<UserEntity>lambdaQuery()
                .eq(UserEntity::getUnionId,pUnionId);

        return baseMapper.selectCount(wrapper).intValue();
    }
}

3.2 PlayerScoreDbService

public interface IPlayerScoreDbService extends IZfDbService<PlayerScoreEntity> {
    PlayerScoreEntity find(Long pPlayerId, Long pBattleId);
}

@Service
public class PlayerScoreDbServiceImpl extends ZfDbServiceImpl<PlayerScoreMapper, PlayerScoreEntity> implements IPlayerScoreDbService {

    @Override
    public PlayerScoreEntity find(Long pPlayerId, Long pBattleId) {
        LambdaQueryWrapper<PlayerScoreEntity> queryWrapper = Wrappers.<PlayerScoreEntity>lambdaQuery()
                .eq(PlayerScoreEntity::getPlayerId,pPlayerId)
                .eq(PlayerScoreEntity::getBattleId,pBattleId);
        return super.findOne(queryWrapper);
    }
}

3.3 PlayerBattleDayDbService

public interface IPlayerBattleDayDbService extends IZfDbService<PlayerBattleDayEntity> {
    PlayerBattleDayEntity find(Long pPlayerId, Long pBattleId, Integer pDay);
}

@Service
public class PlayerBattleDayDbServiceImpl extends ZfDbServiceImpl<PlayerBattleDayMapper, PlayerBattleDayEntity> implements IPlayerBattleDayDbService {
    @Override
    public PlayerBattleDayEntity find(Long pPlayerId, Long pBattleId, Integer pDay) {

        LambdaQueryWrapper<PlayerBattleDayEntity> queryWrapper = Wrappers.<PlayerBattleDayEntity>lambdaQuery()
                .eq(PlayerBattleDayEntity::getPlayerId,pPlayerId)
                .eq(PlayerBattleDayEntity::getBattleId,pBattleId)
                .eq(PlayerBattleDayEntity::getDay,pDay);
        return super.findOne(queryWrapper);
    }
}

3.4 UnionScoreDbService

public interface IUnionScoreDbService extends IZfDbService<UnionScoreEntity> {
    List<UnionScoreEntity> listByYearAndConstellation(int pYear, EConstellation pConstellation);
    UnionScoreEntity find(Long pUnionId, Long pBattleId);
}

@Service
public class UnionScoreDbServiceImpl extends ZfDbServiceImpl<UnionScoreMapper, UnionScoreEntity> implements IUnionScoreDbService {
    @Override
    public List<UnionScoreEntity> listByYearAndConstellation(int pYear, EConstellation pConstellation) {
        LambdaQueryWrapper<UnionScoreEntity> queryWrapper = Wrappers.<UnionScoreEntity>lambdaQuery()
                .eq(UnionScoreEntity::getYear,pYear)
                .eq(UnionScoreEntity::getConstellation,pConstellation)
                .orderByDesc(UnionScoreEntity::getScore);
        List<UnionScoreEntity> unionScoreEntityList = baseMapper.selectList(queryWrapper);
        return unionScoreEntityList;
    }

    @Override
    public UnionScoreEntity find(Long pUnionId, Long pBattleId) {
        LambdaQueryWrapper<UnionScoreEntity> queryWrapper = Wrappers.<UnionScoreEntity>lambdaQuery()
                .eq(UnionScoreEntity::getUnionId, pUnionId)
                .eq(UnionScoreEntity::getBattleId, pBattleId);
        return super.findOne(queryWrapper);
    }
}

3.5 BattleDbService

public interface IBattleDbService extends IZfDbService<BattleEntity> {
    BattleEntity findByUnionIdAndYearAndConstellation(Long pUnionId, int pYear, EConstellation pEConstellation);
}

@Service
public class BattleDbServiceImpl extends ZfDbServiceImpl<BattleMapper, BattleEntity> implements IBattleDbService {

    @Override
    public BattleEntity findByUnionIdAndYearAndConstellation(Long pUnionId, int pYear, EConstellation pEConstellation) {
        LambdaQueryWrapper<BattleEntity> queryWrapper = Wrappers.<BattleEntity>lambdaQuery()
                .eq(BattleEntity::getUnionId,pUnionId)
                .eq(BattleEntity::getYear,pYear)
                .eq(BattleEntity::getConstellation,pEConstellation);
        return super.findOne(queryWrapper);
    }
}

3.6 HitDbService

public interface IHitDbService extends IZfDbService<HitEntity> {
    List<HitEntity> listByUserIdAndBattleIdAndDay(Long pUserId, Long pBattleId, Integer pDay);
    List<HitEntity> listByBattleId(Long pBattleId);
}

@Service
public class HitDbServiceImpl extends ZfDbServiceImpl<HitMapper, HitEntity> implements IHitDbService {

    @Override
    public List<HitEntity> listByUserIdAndBattleIdAndDay(Long pUserId, Long pBattleId, Integer pDay) {
        LambdaQueryWrapper<HitEntity> queryWrapper = Wrappers.<HitEntity>lambdaQuery()
                .eq(HitEntity::getUserId,pUserId)
                .eq(HitEntity::getBattleId,pBattleId)
                .eq(HitEntity::getDay,pDay);
        List<HitEntity> hitEntityList = baseMapper.selectList(queryWrapper);
        hitEntityList.sort((left,right)->{
            if(!left.getHitIndex().equals(right.getHitIndex())){
                return left.getHitIndex() - right.getHitIndex();
            }else{
                return left.getHitType().getCode() - right.getHitType().getCode();
            }
        });
        return hitEntityList;
    }

    @Override
    public List<HitEntity> listByBattleId(Long pBattleId) {
        LambdaQueryWrapper<HitEntity> queryWrapper = Wrappers.<HitEntity>lambdaQuery()
                .eq(HitEntity::getBattleId, pBattleId);
        List<HitEntity> hitEntityList = baseMapper.selectList(queryWrapper);
        return hitEntityList;
    }
}

四、Game 业务实现

根据第一章的介绍,这里直接给出代码。
注意:真是生产环境,Game服务器可能是集群,所以mBattleOn,mYear,mConstellation,mDay这4个变量不能简单的放在GameService中,可以单独搞个管理微服务,只放1台服务器,用这台服务器去管理全局进度。在部署上,推荐把这种服务器和nacos放在一个docker里,以最大化资源利用率。

@RequiredArgsConstructor
@Service
public class GameServiceImpl implements IGameService {

    boolean mBattleOn;
    int mYear;
    EConstellation mConstellation;
    int mDay;

    final IBattleDbService mBattleDbService;
    final IUserDbService mUserDbService;
    final IHitDbService mHitDbService;
    final IUnionScoreDbService mUnionScoreDbService;
    final IUnionDbService mUnionDbService;
    final IPlayerScoreDbService mPlayerScoreDbService;
    final IPlayerBattleDayDbService mPlayerBattleDayDbService;
    final IBossDbService mBossDbService;
    final AppProperty mAppProperty;
    final BossTypeMemo mBossTypeMemo;
    final ISysDataDbService mSysDataDbService;

    @Transactional(rollbackFor = Exception.class)
    @PostConstruct
    void init(){
        mYear = checkVal("year",EValueType.INTEGER,"0").intVal();
        mDay = checkVal("day",EValueType.INTEGER,"0").intVal();
        mConstellation = EConstellation.values()[checkVal("constellation",EValueType.INTEGER,"0").intVal()];
        mBattleOn = checkVal("battleOn",EValueType.BOOLEAN,"false").booleanVal();
    }

    protected SysDataEntity checkVal(String pKey, EValueType pType, String pDefault){
        SysDataEntity sysDataEntity = mSysDataDbService.getById(pKey);
        if(null == sysDataEntity){
            sysDataEntity = new SysDataEntity();
            sysDataEntity.createInit();
            sysDataEntity.setKey(pKey);
            sysDataEntity.setType(pType);
            sysDataEntity.setValue(pDefault);
            mSysDataDbService.save(sysDataEntity);
        }
        return sysDataEntity;
    }

    protected void synchronousSysData(int pYear, int pDay, EConstellation pConstellation, boolean pBattleOn){
        SysDataEntity[] sysDatas = new SysDataEntity[4];
        sysDatas[0] = checkVal("year",EValueType.INTEGER,"0");
        sysDatas[0].setValue(String.valueOf(pYear));

        sysDatas[1] = checkVal("day",EValueType.INTEGER,"0");
        sysDatas[1].setValue(String.valueOf(pDay));

        sysDatas[2] = checkVal("constellation",EValueType.INTEGER,"0");
        sysDatas[2].setValue(String.valueOf(pConstellation.getCode()));

        sysDatas[3] = checkVal("battleOn",EValueType.INTEGER,"false");
        sysDatas[3].setValue(pBattleOn ? "true": "false");

        mSysDataDbService.updateBatchById(Arrays.asList(sysDatas));
        mYear = pYear;
        mDay = pDay;
        mConstellation = pConstellation;
        mBattleOn = pBattleOn;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void startBattle(int pYear, EConstellation pEConstellation) {

        if(mBattleOn){
            throw new ServiceException("公会战还在进行中");
        }

        synchronousSysData(pYear,1,pEConstellation,true);

        List<BattleEntity> newBattleEntityList = new ArrayList<>();
        List<UnionScoreEntity> unionScoreEntityList = new ArrayList<>();
        List<BossEntity> newBoss = new ArrayList<>();
        List<HitEntity> newHitList = new ArrayList<>();
        List<UnionEntity> editingUnionList = new ArrayList<>();
        List<PlayerScoreEntity> newPlayerScoreEntityList = new ArrayList<>();
        List<PlayerBattleDayEntity> newPlayerBattleDayEntityList = new ArrayList<>();

        Page<UnionEntity>  pageData = mUnionDbService.page(new Page<>(1,100));

        for(int current=1; current <= pageData.getPages(); current++){
            Page<UnionEntity> unionPage;
            if(current == 1){
                unionPage = pageData;
            }
            unionPage = mUnionDbService.page(new Page<>(current,100));
            List<UnionEntity> unionEntityList = unionPage.getRecords();
            for(UnionEntity unionEntity : unionEntityList){
                // 创建公会战
                BattleEntity battle = new BattleEntity();
                battle.createInit();
                battle.setUnionId(unionEntity.getId());
                battle.setYear(pYear);
                battle.setConstellation(pEConstellation);
                battle.setRound(1);
                battle.setBossIdx(1);
                battle.setDay(1);
                battle.setStatus(EBattleStatus.ON_GOING);
                newBattleEntityList.add(battle);
                unionEntity.setBattleId(battle.getId());
                editingUnionList.add(unionEntity);
                // 创建公会分数实体
                UnionScoreEntity unionScoreEntity = new UnionScoreEntity();
                unionScoreEntity.createInit();
                unionScoreEntity.setYear(pYear);
                unionScoreEntity.setConstellation(pEConstellation);
                unionScoreEntity.setUnionId(unionEntity.getId());
                unionScoreEntity.setBattleId(battle.getId());
                unionScoreEntity.setUnionName(unionEntity.getName());
                unionScoreEntity.setRound(0);
                unionScoreEntity.setScore(0);
                unionScoreEntity.setBossIdx(battle.getBossIdx());
                unionScoreEntity.setBattleId(battle.getId());
                unionScoreEntityList.add(unionScoreEntity);
                // 创建BOSS
                BossEntity bossEntity = genBoss(battle);
                newBoss.add(bossEntity);
                battle.setBossId(bossEntity.getId());
                // 为公会每位成员建刀
                List<UserEntity> userEntityList = mUserDbService.listByUnionId(unionEntity.getId());
                for(UserEntity userEntity : userEntityList){
                    for(int day=1;day<=mAppProperty.getBattleDays();day++){
                        // 创建玩家每日数据
                        PlayerBattleDayEntity playerBattleDayEntity = new PlayerBattleDayEntity();
                        playerBattleDayEntity.createInit();
                        playerBattleDayEntity.setPlayerId(userEntity.getId());
                        playerBattleDayEntity.setBattleId(battle.getId());
                        playerBattleDayEntity.setDay(day);
                        playerBattleDayEntity.setPlayerName(userEntity.getNickName());
                        playerBattleDayEntity.setSl(false);
                        playerBattleDayEntity.setHitWhole(0);
                        playerBattleDayEntity.setHitTail(0);
                        playerBattleDayEntity.setHitCompensate(0);
                        newPlayerBattleDayEntityList.add(playerBattleDayEntity);
                        // 创建刀数据
                        for(int hitIdx=1;hitIdx<=mAppProperty.getDayHits();hitIdx++){
                            HitEntity hitEntity = new HitEntity();
                            hitEntity.createInit();
                            hitEntity.setUnionId(unionEntity.getId());
                            hitEntity.setBattleId(battle.getId());
                            hitEntity.setUserId(userEntity.getId());
                            hitEntity.setNickName(userEntity.getNickName());
                            hitEntity.setDone(false);
                            hitEntity.setDay(day+1);
                            hitEntity.setHitIndex(hitIdx+1);
                            hitEntity.setBossId(-1L);
                            hitEntity.setHitType(EHitType.WHOLE);
                            hitEntity.setDemage(-1);
                            hitEntity.setScore(-1);
                            newHitList.add(hitEntity);
                        }
                    }
                    // 创建分数
                    PlayerScoreEntity playerScoreEntity = new PlayerScoreEntity();
                    playerScoreEntity.createInit();
                    playerScoreEntity.setPlayerId(userEntity.getId());
                    playerScoreEntity.setBattleId(battle.getId());
                    playerScoreEntity.setPlayerName(userEntity.getNickName());
                    playerScoreEntity.setDemage(0);
                    playerScoreEntity.setScore(0);
                    newPlayerScoreEntityList.add(playerScoreEntity);
                }
            }
        }
        mBattleDbService.saveBatch(newBattleEntityList);
        mUnionScoreDbService.saveBatch(unionScoreEntityList);
        mBossDbService.saveBatch(newBoss);
        mHitDbService.saveBatch(newHitList);
        mUnionDbService.updateBatchById(editingUnionList);
        mPlayerScoreDbService.saveBatch(newPlayerScoreEntityList);
        mPlayerBattleDayDbService.saveBatch(newPlayerBattleDayEntityList);
    }


    protected void battleOver(){
        // 计算排名
        List<UnionScoreEntity> unionScoreEntityList = mUnionScoreDbService.listByYearAndConstellation(mYear,mConstellation);
        Map<Long, RankData> unionScoreEntityMap = new HashMap<>();
        for(int i=0;i<unionScoreEntityList.size();i++){
            UnionScoreEntity unionScoreEntity = unionScoreEntityList.get(i);
            RankData rankData = DtoEntityUtil.trans(unionScoreEntity,RankData.class);
            rankData.setRank(i+1);
            unionScoreEntityMap.put(unionScoreEntity.getUnionId(),rankData);
        }
        // 遍历所有公会,battleId设置为-1,设置scoreId
        List<UnionEntity> unionEntityList = mUnionDbService.list();
        for(UnionEntity unionEntity : unionEntityList){
            RankData rankData = unionScoreEntityMap.get(unionEntity.getId());
            if(null != rankData){
                unionEntity.setScoreId(rankData.getUnionId());
                unionEntity.setRank(rankData.getRank());
            }
        }
        mUnionDbService.updateBatchById(unionEntityList);
    }

    @Override
    public Integer dayPass() {

        if(!mBattleOn){
            throw new ServiceException("没有开启公会战");
        }

        int day = mDay + 1;
        boolean battleOn = true;
        if(day > mAppProperty.getBattleDays()){
            battleOver();
            battleOn = false;
            day = 0;
        }
        synchronousSysData(mYear,day,mConstellation,battleOn);

        Page<BattleEntity> battleFirstPage = mBattleDbService.page(new Page<>(1,100));
        for(int current=1; current <= battleFirstPage.getPages(); current++){
            Page<BattleEntity> battleEntityPage;
            if(1 == current){
                battleEntityPage = battleFirstPage;
            }else{
                battleEntityPage = mBattleDbService.page(new Page<>(current,mAppProperty.getPageSize()));
            }
            List<BattleEntity> battleEntityList = battleEntityPage.getRecords();
            for(BattleEntity battleEntity : battleEntityList){
                if(!mBattleOn){
                    battleEntity.setStatus(EBattleStatus.FINISH);
                }else{
                    battleEntity.setDay(mDay);
                }
            }
            mBattleDbService.updateBatchById(battleEntityList);
        }
        if(mBattleOn){
            return mDay;
        }else {
            return 0;
        }
    }

    @Data
    class CheckHitResponse{
        UserEntity userEntity;
        UnionEntity unionEntity;
        UnionScoreEntity unionScoreEntity;
        BattleEntity battleEntity;
        BossEntity bossEntity;
        HitEntity hitEntity;
    }

    protected CheckHitResponse checkHitResponse(Long pPlayerId){
        CheckHitResponse checkHitResponse = new CheckHitResponse();
        if(!mBattleOn){
            throw new ServiceException("没有开启公会战");
        }
        UserEntity userEntity = checkPlayer(pPlayerId);
        Long unionId = userEntity.getUnionId();
        if(null == unionId){
            throw new ServiceException("玩家"+userEntity.getNickName()+"没有加入公会");
        }
        UnionEntity unionEntity = checkUnion(unionId);
        Long battleId = unionEntity.getBattleId();
        if(null == battleId){
            throw new ServiceException("没有开启公会战");
        }
        UnionScoreEntity unionScoreEntity = mUnionScoreDbService.find(unionEntity.getId(),battleId);
        if(null == unionScoreEntity){
            throw new ServiceException("会战积分实体缺失");
        }

        BattleEntity battleEntity = checkBattle(battleId);
        Long bossId = battleEntity.getBossId();
        BossEntity bossEntity = checkBoss(bossId);

        HitEntity hitEntity = getCurrentHit(userEntity,battleEntity);
        if(null == hitEntity){
            throw new ServiceException("今天刀出完了");
        }
        checkHitResponse.setUserEntity(userEntity);
        checkHitResponse.setUnionEntity(unionEntity);
        checkHitResponse.setUnionScoreEntity(unionScoreEntity);
        checkHitResponse.setBattleEntity(battleEntity);
        checkHitResponse.setBossEntity(bossEntity);
        checkHitResponse.setHitEntity(hitEntity);
        return checkHitResponse;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public HitResultVo hit(Long pPlayerId, Integer pDamage) {

        CheckHitResponse hitResponse = checkHitResponse(pPlayerId);
        BossEntity bossEntity = hitResponse.getBossEntity();
        HitEntity hitEntity = hitResponse.getHitEntity();

        int hp = bossEntity.getHp();
        if(hp >= pDamage){
            hp = hp - pDamage;
            bossEntity.setHp(hp);
            if(hp == 0){
                bossEntity.setAlive(false);
                nextBoss(hitResponse.getBattleEntity(),hitResponse.getUnionScoreEntity());
            }
            hitEntity.setDone(true);
            Integer score = getScore(bossEntity.getBossType(), pDamage);
            hitEntity.setDemage(pDamage);
            hitEntity.setScore(score);
            hitEntity.setDone(true);
            hitEntity.setBossId(bossEntity.getId());
            mBossDbService.updateById(bossEntity);
            mHitDbService.updateById(hitEntity);

        }else{
            throw new ServiceException("伤害超过BOSS血量,请使用尾刀报刀");
        }
        HitResultVo hitResultVo = DbDtoEntityUtil.trans(hitEntity,HitResultVo.class);
        hitResultVo.setBossStatus(bossEntity);

        // 处理排行榜
        handleRankList(hitEntity);
        return hitResultVo;
    }

    protected HitEntity getCurrentHit(UserEntity pPlayer, BattleEntity pBattle){
        List<HitEntity> hitEntityList = mHitDbService.listByUserIdAndBattleIdAndDay(pPlayer.getId(),pBattle.getId(),pBattle.getDay());
        if(CollectionUtils.isEmpty(hitEntityList)){
            throw new ServiceException("出刀数据缺失");
        }
        if(hitEntityList.get(hitEntityList.size()-1).getDone()){
            // 今日刀出完了
            return null;
        }
        for(int i=0;i<hitEntityList.size();i++){
            HitEntity hitEntity = hitEntityList.get(i);
            if(!hitEntity.getDone()){
                return hitEntity;
            }
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public HitResultVo tail(Long pPlayerId) {
        CheckHitResponse hitResponse = checkHitResponse(pPlayerId);
        BossEntity bossEntity = hitResponse.getBossEntity();
        HitEntity hitEntity = hitResponse.getHitEntity();
        Integer damage = bossEntity.getHp();
        bossEntity.setHp(0);
        bossEntity.setAlive(false);
        Integer score = getScore(bossEntity.getBossType(), damage);
        hitEntity.setDemage(damage);
        hitEntity.setScore(score);
        hitEntity.setHitType(EHitType.TAIL);
        hitEntity.setDone(true);
        hitEntity.setBossId(bossEntity.getId());
        BossEntity nextBoss = nextBoss(hitResponse.getBattleEntity(),hitResponse.getUnionScoreEntity());
        mBossDbService.updateById(bossEntity);
        mHitDbService.updateById(hitEntity);

        HitResultVo hitResultVo = DbDtoEntityUtil.trans(hitEntity,HitResultVo.class);
        hitResultVo.setBossStatus(nextBoss);

        // 创建补偿刀
        HitEntity hitCompensate = new HitEntity();
        hitCompensate.createInit();
        hitCompensate.setUserId(pPlayerId);
        hitCompensate.setNickName(hitResponse.getUserEntity().getNickName());
        hitCompensate.setUnionId(hitResponse.getUnionEntity().getId());
        hitCompensate.setBattleId(hitResponse.getBattleEntity().getId());
        hitCompensate.setBossId(nextBoss.getId());
        hitCompensate.setDone(false);
        hitCompensate.setDemage(0);
        hitCompensate.setScore(0);
        hitCompensate.setDay(hitEntity.getDay());
        hitCompensate.setHitIndex(hitEntity.getHitIndex());
        hitCompensate.setHitType(EHitType.COMPENSATE);
        mHitDbService.save(hitCompensate);
        // 处理排行榜
        handleRankList(hitEntity);

        return hitResultVo;
    }

    protected void handleRankList(HitEntity pHit){
        // 玩家会战日数据
        PlayerBattleDayEntity playerBattleDayEntity = mPlayerBattleDayDbService.find(pHit.getUserId(),pHit.getBattleId(),pHit.getDay());
        if(null == playerBattleDayEntity){
            throw new ServiceException("PlayerBattleDayEntity数据缺失");
        }
        switch (pHit.getHitType()) {
            case WHOLE:
                playerBattleDayEntity.setHitWhole(playerBattleDayEntity.getHitWhole()+1);
                break;
            case TAIL:
                playerBattleDayEntity.setHitTail(playerBattleDayEntity.getHitTail()+1);
                break;
            case COMPENSATE:
                playerBattleDayEntity.setHitCompensate(playerBattleDayEntity.getHitCompensate()+1);
                break;
        }
        mPlayerBattleDayDbService.updateById(playerBattleDayEntity);
        // 玩家会战积分
        PlayerScoreEntity playerScoreEntity = mPlayerScoreDbService.find(pHit.getUserId(),pHit.getBattleId());
        if(null == playerScoreEntity){
            throw new ServiceException("PlayerScoreEntity数据缺失");
        }
        playerScoreEntity.setScore(playerScoreEntity.getScore()+pHit.getScore());
        playerScoreEntity.setDemage(playerScoreEntity.getDemage()+pHit.getDemage());
        mPlayerScoreDbService.updateById(playerScoreEntity);
        // 公会会战积分
        UnionScoreEntity unionScoreEntity = mUnionScoreDbService.find(pHit.getUnionId(),pHit.getBattleId());
        unionScoreEntity.setScore(unionScoreEntity.getScore() + pHit.getScore());
        mUnionScoreDbService.updateById(unionScoreEntity);
    }

    @Override
    public BattleInfoVo status(BattleEntity pBattleEntity) {
        BattleInfoVo battleInfoVo = DtoEntityUtil.trans(pBattleEntity,BattleInfoVo.class);
        List<HitEntity> hitEntityList = mHitDbService.listByBattleId(pBattleEntity.getId());
        for(HitEntity hitEntity : hitEntityList){
            if(hitEntity.getDone()){
                switch (hitEntity.getHitType()) {
                    case WHOLE:
                        battleInfoVo.setHitWhole(battleInfoVo.getHitWhole()+1);
                        if(hitEntity.getDay().equals(pBattleEntity.getDay())){
                            battleInfoVo.setHitWholeDay(battleInfoVo.getHitWholeDay()+1);
                        }
                        break;
                    case TAIL:
                        battleInfoVo.setHitTail(battleInfoVo.getHitTail()+1);
                        if(hitEntity.getDay().equals(pBattleEntity.getDay())){
                            battleInfoVo.setHitTailDay(battleInfoVo.getHitTailDay()+1);
                        }
                        break;
                    case COMPENSATE:
                        battleInfoVo.setHitCompensate(battleInfoVo.getHitCompensate()+1);
                        if(hitEntity.getDay().equals(pBattleEntity.getDay())){
                            battleInfoVo.setHitCompensateDay(battleInfoVo.getHitCompensateDay()+1);
                        }
                        break;
                }
            }
        }
        Long bossId = pBattleEntity.getBossId();
        BossEntity bossEntity = checkBoss(bossId);
        battleInfoVo.setBossStatus(bossEntity);
        return battleInfoVo;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public BattleInfoVo withDraw(Long pUnionId) {
        throw new ServiceException("没有实现");
    }

    @Override
    public Integer getDay() {
        return mDay;
    }

    @Override
    public Integer getYear() {
        return mYear;
    }

    @Override
    public EConstellation getConstellation() {
        return mConstellation;
    }

    @Override
    public boolean isBattleOn() {
        return mBattleOn;
    }

    protected int getPhase(int pRound){
        int phase;
        if(pRound <= 3){
            phase = 1;
        }else if(pRound <= 9){
            phase = 2;
        }else{
            phase = 3;
        }
        return phase;
    }

    protected BossEntity nextBoss(BattleEntity pBattleEntity,UnionScoreEntity pUnionScoreEntity){
        int round = pBattleEntity.getRound();
        int bossIdx = pBattleEntity.getBossIdx() + 1;
        if(bossIdx > 5){
            bossIdx = bossIdx -5;
            round++;
        }
        pBattleEntity.setRound(round);
        pBattleEntity.setBossIdx(bossIdx);
        BossEntity bossEntity = genBoss(pBattleEntity);
        pBattleEntity.setBossId(bossEntity.getId());
        pUnionScoreEntity.setRound(round);
        pUnionScoreEntity.setBossIdx(bossIdx);
        mBattleDbService.updateById(pBattleEntity);
        mUnionScoreDbService.updateById(pUnionScoreEntity);
        mBossDbService.save(bossEntity);
        return bossEntity;
    }

    protected BossEntity genBoss(BattleEntity pBattleEntity){
        int round = pBattleEntity.getRound();
        int bossIdx = pBattleEntity.getBossIdx();
        int phase = getPhase(round);
        int bossId = phase * 100 + bossIdx;
        EBossType bossType = mBossTypeMemo.get(bossId);
        BossEntity bossEntity = new BossEntity();
        bossEntity.createInit();
        bossEntity.setBossType(bossType);
        bossEntity.setBattleId(pBattleEntity.getId());
        bossEntity.setAlive(true);
        bossEntity.setHp(bossType.getMaxHp());
        return bossEntity;
    }

    protected UnionEntity checkUnion(Long pUnionId){
        UnionEntity unionEntity = mUnionDbService.getById(pUnionId);
        if(null == unionEntity){
            throw new ServiceException("没有找到Id为"+pUnionId+"的公会Id");
        }
        return unionEntity;
    }

    protected UserEntity checkPlayer(Long pId){
        UserEntity userEntity = mUserDbService.getById(pId);
        if(null == userEntity){
            throw new ServiceException("没找到Id为"+pId+"的玩家Id");
        }
        return userEntity;
    }

    protected BattleEntity checkBattle(Long pId){
        BattleEntity battleEntity = mBattleDbService.getById(pId);
        if(null == battleEntity){
            throw new ServiceException("没有找到Id为"+pId+"的战斗Id");
        }
        return battleEntity;
    }

    protected BossEntity checkBoss(Long pId){
        BossEntity bossEntity = mBossDbService.getById(pId);
        if(null == bossEntity){
            throw new ServiceException("没有找到Id为"+pId+"Boss");
        }
        return bossEntity;
    }

    protected Integer getScore(EBossType pBossType, Integer pDamage){
        return (int)(pBossType.getFactor() * pDamage);
    }

}

五、其他业务实现

其他业务没有太多好讲的,故省去接口代码,只留实现代码

5.1 UserService

@RequiredArgsConstructor
@Service
public class UserServiceImpl implements IUserService {

    final IUserDbService mUserDbService;
    final IUnionDbService mUnionDbService;
    final IGameService mGameService;
    final AppProperty mAppProperty;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity create(UserDto pUserDto) {
        UserEntity userEntity = DbDtoEntityUtil.dtoToPo(pUserDto,UserEntity.class);
        userEntity.setUnionId(-1L);
        mUserDbService.save(userEntity);
        return userEntity;
    }

    @Override
    public UserEntity info(Long pId) {
        UserEntity userEntity = check(pId);
        return userEntity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(Long pId) {
        check(pId);
        mUserDbService.removeById(pId);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity edit(Long pId, UserDto pUserDto) {
        UserEntity userEntity = check(pId);
        UserEntity newUserEntity = DbDtoEntityUtil.dtoToPo(pUserDto,userEntity,UserEntity.class);
        mUserDbService.updateById(newUserEntity);
        return newUserEntity;
    }

    @Override
    public Page<UserEntity> page(int pCurrent, int pSize, String pName, Long pUnionId) {
        Page<UserEntity> pageConfig = new Page<UserEntity>(pCurrent,pSize);
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = Wrappers.<UserEntity>lambdaQuery();
        if(StringUtils.hasText(pName)){
            lambdaQueryWrapper = lambdaQueryWrapper.like(UserEntity::getNickName,pName);
        }
        if(null != pUnionId){
            lambdaQueryWrapper = lambdaQueryWrapper.eq(UserEntity::getUnionId,pUnionId);
        }
        Page<UserEntity> pageData = mUserDbService.page(pageConfig,lambdaQueryWrapper);
        return pageData;
    }

    protected UserEntity check(Long pId){
        UserEntity userEntity = mUserDbService.getById(pId);
        if(null == userEntity){
            throw new ServiceException("没有找到Id为"+pId+"的用户数据");
        }
        return userEntity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity join(Long pUserId, Long pUnionId) {
        UserEntity orgUserEntity = check(pUserId);
        if(-1L != orgUserEntity.getUnionId()){
            throw new ServiceException("必须先退出公会,才能加入新公会");
        }
        UnionEntity unionEntity = mUnionDbService.getById(pUnionId);
        if(null == unionEntity){
            throw new ServiceException("没有找到Id为"+pUnionId+"的公会");
        }
        if(mGameService.isBattleOn()){
            throw new ServiceException("会战期间不可加入公会");
        }
        int playerCnt = mUserDbService.countByUnionId(pUnionId);
        if(playerCnt >= mAppProperty.getMaxUnionPlayerNum()){
            throw new ServiceException("该公会人数已满,不可再加入");
        }


        UserEntity newUserEntity = new UserEntity();
        newUserEntity.updateInit();
        newUserEntity.setId(pUserId);
        newUserEntity.setUnionId(pUnionId);
        mUserDbService.updateById(newUserEntity);
        orgUserEntity.setUnionId(pUnionId);
        return orgUserEntity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserEntity quit(Long pUserId) {
        UserEntity orgUserEntity = check(pUserId);
        if(-1L == orgUserEntity.getUnionId()){
            throw new ServiceException("已经退出公会,没必要重复退出");
        }
        if(mGameService.isBattleOn()){
            throw new ServiceException("会战期间不可退出公会");
        }
        UserEntity newUserEntity = new UserEntity();
        newUserEntity.updateInit();
        newUserEntity.setId(pUserId);
        newUserEntity.setUnionId(-1L);
        mUserDbService.updateById(newUserEntity);
        orgUserEntity.setUnionId(-1L);
        return orgUserEntity;
    }
}

5.2 UnionService

@RequiredArgsConstructor
@Service
public class UnionServiceImpl implements IUnionService {

    final IUnionDbService mUnionDbService;
    final IGameService mGameService;
    final IBattleDbService mBattleDbService;
    final IUserDbService mUserDbService;
    final IUnionScoreDbService mUnionScoreDbService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UnionEntity create(UnionDto pUnionDto) {
        UnionEntity unionEntity = DbDtoEntityUtil.dtoToPo(pUnionDto,UnionEntity.class);
        unionEntity.setBattleId(-1L);
        unionEntity.setRank(-1);
        unionEntity.setScoreId(-1L);
        mUnionDbService.save(unionEntity);
        return unionEntity;
    }

    @Override
    public UnionVo info(Long pId) {
        UnionEntity unionEntity = check(pId);
        UnionVo unionVo = DtoEntityUtil.trans(unionEntity,UnionVo.class);
        Integer memberCnt = mUserDbService.countByUnionId(pId);
        unionVo.setMemberNum(memberCnt);
        if(null != unionEntity.getScoreId()&&unionEntity.getScoreId() > 0){
            UnionScoreEntity unionScoreEntity = mUnionScoreDbService.getById(unionEntity.getScoreId());
            unionVo.setUnionScore(unionScoreEntity);
        }
        return unionVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(Long pId) {
        check(pId);
        mUnionDbService.removeById(pId);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UnionEntity edit(Long pId, UnionDto pUnionDto) {
        UnionEntity oldUnionEntity = check(pId);
        UnionEntity newUnionEntity = DbDtoEntityUtil.dtoToPo(pUnionDto,oldUnionEntity,UnionEntity.class);
        mUnionDbService.updateById(newUnionEntity);
        return newUnionEntity;
    }

    @Override
    public Page<UnionEntity> page(int pCurrent, int pSize, String pName) {
        Page<UnionEntity> pageConfig = new Page<>(pCurrent,pSize);
        LambdaQueryWrapper<UnionEntity> queryWrapper = Wrappers.<UnionEntity>lambdaQuery();
        if(StringUtils.hasText(pName)){
            queryWrapper = queryWrapper.like(UnionEntity::getName,pName);
        }
        queryWrapper = queryWrapper.orderByAsc(UnionEntity::getRank);
        return mUnionDbService.page(pageConfig,queryWrapper);
    }

    @Override
    public BattleInfoVo status(Long pUnionId) {
        UnionEntity unionEntity = check(pUnionId);
        if(!mGameService.isBattleOn()){
            throw new ServiceException("会战没有开始");
        }
        Long battleId = unionEntity.getBattleId();
        BattleEntity battleEntity = checkBattle(battleId);
        BattleInfoVo battleInfoVo = mGameService.status(battleEntity);
        return battleInfoVo;
    }

    protected UnionEntity check(Long pId){
        UnionEntity unionEntity = mUnionDbService.getById(pId);
        if(null == unionEntity){
            throw new ServiceException("没有找到Id为"+pId+"的公会");
        }
        return unionEntity;
    }

    protected BattleEntity checkBattle(Long pBattleId){
        BattleEntity battleEntity = mBattleDbService.getById(pBattleId);
        if(null == battleEntity){
            throw new ServiceException("没有找到Id为"+pBattleId+"的id");
        }
        return battleEntity;
    }
}

5.3 RankListService

@RequiredArgsConstructor
@Service
public class RankListServiceImpl implements IRankListService {

    final IUnionScoreDbService mUnionScoreDbService;
    final IPlayerScoreDbService mPlayerScoreDbService;
    final IUnionDbService mUnionDbService;
    final IBattleDbService mBattleDbService;
    final IBossDbService mBossDbService;
    final BossTypeMemo mBossTypeMemo;


    @Override
    public PlayerRankListVo rankListForPlayer(Long pUnionId, ERankListSort pSortType) {

        PlayerRankListVo playerRankListVo = new PlayerRankListVo();

        UnionEntity unionEntity = mUnionDbService.getById(pUnionId);
        if(null == unionEntity){
            throw new ServiceException("没有找到Id为"+pUnionId+"的公会Id");
        }
        Long battleId = unionEntity.getBattleId();
        if(null == battleId){
            throw new ServiceException("公会"+pUnionId+"还没进行过公会战");
        }
        BattleEntity battleEntity = mBattleDbService.getById(battleId);
        if(null == battleEntity){
            throw new ServiceException("没有找到Id为"+battleId+"的");
        }

        playerRankListVo.setBattleId(battleId);
        playerRankListVo.setYear(battleEntity.getYear());
        playerRankListVo.setConstellation(battleEntity.getConstellation());
        playerRankListVo.setUnionId(pUnionId);
        playerRankListVo.setUnionName(unionEntity.getName());

        LambdaQueryWrapper<PlayerScoreEntity> queryWrapper = Wrappers.<PlayerScoreEntity>lambdaQuery()
                .eq(PlayerScoreEntity::getBattleId,battleId);
        switch (pSortType) {
            case SCORE:
                queryWrapper.orderByDesc(PlayerScoreEntity::getScore);
                break;
            case DAMAGE:
                queryWrapper.orderByDesc(PlayerScoreEntity::getDemage);
                break;
        }

        List<PlayerRankListItemVo> scoreVoList = mPlayerScoreDbService.list(queryWrapper,PlayerRankListItemVo.class);
        playerRankListVo.setData(scoreVoList);
        return playerRankListVo;
    }

    @Override
    public UnionRankListVo rankListForUnion(Integer pCurrent, Integer pSize, Integer pYear, EConstellation pConstellation) {
        LambdaQueryWrapper<UnionScoreEntity> queryWrapper = Wrappers.<UnionScoreEntity>lambdaQuery()
                .eq(UnionScoreEntity::getYear,pYear)
                .eq(UnionScoreEntity::getConstellation,pConstellation)
                .orderByDesc(UnionScoreEntity::getScore);
        Page<UnionRankListItemVo> unionScoreEntityPage = mUnionScoreDbService.page(new Page<>(pCurrent,pSize), queryWrapper,
                UnionRankListItemVo.class, (po)->{
                    UnionRankListItemVo unionRankListItemVo = DtoEntityUtil.trans(po,UnionRankListItemVo.class);
                    BattleEntity battleEntity = mBattleDbService.getById(po.getBattleId());
                    BossEntity bossEntity = mBossDbService.getById(battleEntity.getBossId());
                    if(null != bossEntity){
                        EBossType bossType = bossEntity.getBossType();
                        unionRankListItemVo.setBossName(bossType.getName());
                    }
                    return unionRankListItemVo;
                });
        UnionRankListVo unionRankListVo = new UnionRankListVo();
        unionRankListVo.setYear(pYear);
        unionRankListVo.setConstellation(pConstellation);
        unionRankListVo.setPage(unionScoreEntityPage);
        return unionRankListVo;
    }

    @Override
    public UnionRankListVo rankListForSelfUnion(Long pUnionId, Integer pYear, EConstellation pConstellation) {
		// 这个接口是返回自己公会前后10名的公会信息
        return null;
    }
}

5.4 HitService

@RequiredArgsConstructor
@Service
public class HitServiceImpl implements IHitService {

    final IHitDbService mHitDbService;
    final IBossDbService mBossDbService;
    final IGameService mGameService;
    final BossTypeMemo mBossTypeMemo;

    protected String getBossNameById(Long pId){
        BossEntity bossEntity = mBossDbService.getById(pId);
        if(null == bossEntity){
            throw new ServiceException("没找到id为"+pId+"的Boss");
        }
        String bossName = bossEntity.getBossType().getName();
        return bossName;
    }

    @Override
    public HitVo info(Long pId) {
        HitEntity hitEntity = checkEntity(pId);
        HitVo hitVo = DbDtoEntityUtil.trans(hitEntity,HitVo.class);
        if(hitEntity.getDone()){
            String bossName = getBossNameById(pId);
            hitVo.setBossName(bossName);
        }
        return hitVo;
    }

    protected HitVo hitPoToVo(HitEntity pHitEntity){
        HitVo hitVo = DtoEntityUtil.trans(pHitEntity,HitVo.class);
        if(hitVo.getDone()){
            String bossName = getBossNameById(hitVo.getBossId());
            hitVo.setBossName(bossName);
        }
        return hitVo;
    }

    @Override
    public List<HitVo> listForPlayer(Long pBattleId, Long pPlayerId, Integer pDay) {
        LambdaQueryWrapper<HitEntity> queryWrapper = Wrappers.<HitEntity>lambdaQuery()
                .eq(HitEntity::getBattleId,pBattleId)
                .eq(HitEntity::getUserId,pPlayerId)
                .eq(HitEntity::getDone,true);
        if(null == pDay){

        }else if(0 == pDay){
            int day = mGameService.getDay();
            queryWrapper = queryWrapper.eq(HitEntity::getDay,day);
        }else{
            queryWrapper = queryWrapper.eq(HitEntity::getDay,pDay);
        }
        List<HitVo> hitVoList = mHitDbService.list(queryWrapper,HitVo.class,po->hitPoToVo(po));
        return hitVoList;
    }

    @Override
    public Page<HitVo> page(int pCurrent, int pSize, Long pBattleId, Long pPlayerId, Long pUnionId) {
        LambdaQueryWrapper<HitEntity> queryWrapper = Wrappers.<HitEntity>lambdaQuery();
        if(null != pBattleId){
            queryWrapper = queryWrapper.eq(HitEntity::getBattleId,pBattleId);
        }
        if(null != pPlayerId){
            queryWrapper = queryWrapper.eq(HitEntity::getUserId,pPlayerId);
        }
        if(null != pUnionId){
            queryWrapper = queryWrapper.eq(HitEntity::getUnionId,pUnionId);
        }
        Page<HitVo> hitVoPage = mHitDbService.page(new Page<>(pCurrent,pSize),queryWrapper,HitVo.class,po->hitPoToVo(po));
        return hitVoPage;
    }


    protected HitEntity checkEntity(Long pId){
        HitEntity hitEntity = mHitDbService.getById(pId);
        if(null == hitEntity){
            throw new ServiceException("没有找到Id为"+pId+"的刀");
        }
        return hitEntity;
    }
}

5.5 BattleService

@RequiredArgsConstructor
@Service
public class BattleServiceImpl implements IBattleService {

    final IBattleDbService mBattleDbService;
    final IGameService mGameService;
    final IUnionDbService mUnionDbService;


    @Override
    public BattleInfoVo status(Long pUnionId) {
        UnionEntity unionEntity = mUnionDbService.getById(pUnionId);
        if(null == unionEntity){
            throw new ServiceException("没有找到Id为"+pUnionId+"的公会");
        }
        Long battleId = unionEntity.getBattleId();
        if(null == battleId){
            throw new ServiceException("会战还未开始");
        }
        BattleEntity battleEntity = check(battleId);
        BattleInfoVo battleInfoVo = mGameService.status(battleEntity);
        return battleInfoVo;
    }

    @Override
    public BattleInfoVo status(Long pUnionId, int pYear, EConstellation pEConstellation) {
        BattleEntity battleEntity = mBattleDbService.findByUnionIdAndYearAndConstellation(pUnionId,pYear,pEConstellation);
        if(null == battleEntity){
            String lg = String.format("union %s , year %s , constellation %s 没有找到",pUnionId,pYear,pEConstellation);
            throw new ServiceException(lg);
        }
        BattleInfoVo battleInfoVo = mGameService.status(battleEntity);
        return battleInfoVo;
    }

    protected BattleEntity check(Long pId){
        BattleEntity battleEntity = mBattleDbService.getById(pId);
        if(null == battleEntity){
            throw new ServiceException("没有找到Id为"+pId+"的Battle");
        }
        return battleEntity;
    }
}

六、controller

6.1 GameApi

@Api(tags = "1.游戏接口")
@RequestMapping("/api/game")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class GameApi {

    final IGameService mGameService;

    @Operation(summary = "开启会战")
    @PostMapping("/start")
    public RestResponse<String> startBattle(
            @Parameter(description = "年") @RequestParam(name = "year") int pYear,
            @Parameter(description = "星座") @RequestParam(name = "constellation") EConstellation pEConstellation){
        mGameService.startBattle(pYear,pEConstellation);
        return RestResponse.ok("开启公会战");
    }

    @Operation(summary = "过1天")
    @PostMapping("/dayPass")
    public Integer dayPass(){
        return mGameService.dayPass();
    }

    @Operation(summary = "报刀")
    @PostMapping("/hit")
    public HitResultVo hit(
            @Parameter(description = "玩家Id") @RequestParam(name = "playerId") Long pPlayerId,
            @Parameter(description = "伤害") @RequestParam(name = "damage") Integer pDamage){
        if(pDamage <= 0){
            throw new ServiceException("报刀伤害必须大于0");
        }
        HitResultVo hitResultVo = mGameService.hit(pPlayerId,pDamage);
        return hitResultVo;
    }

    @Operation(summary = "尾刀")
    @PostMapping("/tail")
    public HitResultVo tail(
            @Parameter(description = "玩家Id") @RequestParam(name = "playerId") Long pPlayerId){
        HitResultVo hitResultVo = mGameService.tail(pPlayerId);
        return hitResultVo;
    }

    /**
     * 获取是公会战第几天
     *
     * @return
     */
    @Operation(summary = "第几天会战")
    @GetMapping("/info/day")
    public Integer getDay(){
        Integer day = mGameService.getDay();
        return day;
    }

    @Operation(summary = "会战年")
    @GetMapping("/info/year")
    public Integer getYear(){
        Integer year = mGameService.getYear();
        return year;
    }

    @Operation(summary = "会战星座")
    @GetMapping("/info/constellatio")
    public EConstellation getConstellation(){
        EConstellation constellatio = mGameService.getConstellation();
        return constellatio;
    }

    @Operation(summary = "是否开启公会战")
    @GetMapping("/info/battleOn")
    public Boolean isBattleOn(){
        return mGameService.isBattleOn();
    }
}

6.2 UserApi

@Api(tags = "5.用户接口")
@RequestMapping("/api/player")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class UserApi {
    final IUserService mUserService;

    @Operation(summary = "创建用户")
    @PostMapping
    public UserEntity create(@RequestBody UserDto pUserDto){
        UserEntity userEntity = mUserService.create(pUserDto);
        return userEntity;
    }

    @Operation(summary = "获取用户信息")
    @GetMapping("/{id}")
    public UserEntity info(@Parameter(description = "用户Id",required = true) @PathVariable(name = "id") Long pId){
        UserEntity userEntity = mUserService.info(pId);
        return userEntity;
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/{id}")
    public Boolean delete(@Parameter(description = "用户Id",required = true) @PathVariable(name = "id") Long pId){
        return mUserService.delete(pId);
    }

    @Operation(summary = "修改用户")
    @PutMapping("/{id}")
    public UserEntity edit(
            @Parameter(description = "用户Id",required = true) @PathVariable(name = "id") Long pId,
            @RequestBody UserDto pUserDto){
        UserEntity userEntity = mUserService.edit(pId,pUserDto);
        return userEntity;
    }

    @Operation(summary = "用户分页")
    @GetMapping("/page")
    public Page<UserEntity> page(
            @Parameter(description = "当前页",required = true) @RequestParam(name = "current") int pCurrent,
            @Parameter(description = "页大小",required = true) @RequestParam(name = "size") int pSize,
            @Parameter(description = "用户名") @RequestParam(name = "name",required = false) String pName,
            @Parameter(description = "公会Id") @RequestParam(name = "unionId",required = false) Long pUnionId){
        Page<UserEntity> userEntityPage =  mUserService.page(pCurrent,pSize,pName,pUnionId);
        return userEntityPage;
    }

    @Operation(summary = "加入公会")
    @PostMapping("/join")
    public UserEntity join(
            @Parameter(description = "用户Id",required = true) @RequestParam(name = "userId") Long pUserId,
            @Parameter(description = "公会Id",required = true) @RequestParam(name = "unionId") Long pUnionId){
        UserEntity userEntity = mUserService.join(pUserId,pUnionId);
        return userEntity;
    }


    @Operation(summary = "退出公会")
    @DeleteMapping("/quit")
    public UserEntity quit(
            @Parameter(description = "用户Id",required = true) @RequestParam(name = "userId") Long pUserId){
        UserEntity userEntity = mUserService.quit(pUserId);
        return userEntity;
    }
}

6.3 UnionApi

@Api(tags = "4.公会接口")
@RequestMapping("/api/union")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class UnionApi {

    final IUnionService mUnionService;

    @Operation(summary = "创建公会")
    @PostMapping
    public UnionEntity create(
            @RequestBody UnionDto pUnionDto){
        UnionEntity unionEntity = mUnionService.create(pUnionDto);
        return unionEntity;
    }

    @Operation(summary = "公会信息")
    @GetMapping("/{id}")
    public UnionVo info(
            @Parameter(description = "公会Id",required = true) @PathVariable(name = "id") Long pId){
        UnionVo unionEntity = mUnionService.info(pId);
        return unionEntity;
    }

    @Operation(summary = "删除")
    @DeleteMapping("/{id}")
    public boolean delete(
            @Parameter(description = "公会Id",required = true) @PathVariable(name = "id") Long pId){
        return mUnionService.delete(pId);
    }

    @Operation(summary = "修改")
    @PutMapping("/{id}")
    public UnionEntity edit(
            @Parameter(description = "公会Id",required = true) @PathVariable(name = "id") Long pId,
            @RequestBody UnionDto pUnionDto){
        UnionEntity unionEntity = mUnionService.edit(pId,pUnionDto);
        return unionEntity;
    }

    @Operation(summary = "分页")
    @PutMapping("/page")
    public Page<UnionEntity> page(
            @Parameter(description = "当前页",required = true) @RequestParam(name = "current") int pCurrent,
            @Parameter(description = "页大小",required = true) @RequestParam(name = "size") int pSize,
            @Parameter(description = "公会名") @RequestParam(name = "name", required = false) String pName){
        Page<UnionEntity> unionEntityPage = mUnionService.page(pCurrent,pSize,pName);
        return unionEntityPage;
    }

    @Operation(summary = "修改")
    @GetMapping("/{id}/status")
    public BattleInfoVo status(
            @Parameter(description = "公会Id") @PathVariable(name = "id") Long pUnionId){
        BattleInfoVo battleInfoVo = mUnionService.status(pUnionId);
        return battleInfoVo;
    }
}

6.4 RankListApi

@Api(tags = "6.排行榜接口")
@RequestMapping("/api/rankList")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class RankListApi {

    final IRankListService mRankListService;
    final IGameService mGameService;

    @Operation(summary = "玩家排行榜")
    @GetMapping("/player/{id}")
    public PlayerRankListVo rankListForPlayer(
            @Parameter(description = "公会Id", required = true) @PathVariable(name = "id")Long pUnionId,
            @Parameter(description = "排序方式") @RequestParam(name = "sortType", required = false) ERankListSort pSortType){
        if(null == pSortType){
            pSortType = ERankListSort.SCORE;
        }
        PlayerRankListVo playerRankListVo = mRankListService.rankListForPlayer(pUnionId,pSortType);
        return playerRankListVo;
    }

    @Operation(summary = "公会排行榜")
    @GetMapping("/union/page")
    public UnionRankListVo rankListForUnion(
            @Parameter(description = "当前页",required = true) @RequestParam(name = "current") Integer pCurrent,
            @Parameter(description = "页大小",required = true) @RequestParam(name = "size") Integer pSize,
            @Parameter(description = "年", required = false) @RequestParam(name = "year", required = false) Integer pYear,
            @Parameter(description = "星座", required = false) @RequestParam(name = "constellation", required = false) EConstellation pConstellation){

        if(null == pYear || null == pConstellation){
            pYear = mGameService.getYear();
            pConstellation = mGameService.getConstellation();
        }

        UnionRankListVo unionRankListVo = mRankListService.rankListForUnion(pCurrent,pSize,pYear,pConstellation);
        return unionRankListVo;
    }
}

6.5 BattleApi

@Api(tags = "2.battle接口")
@RequestMapping("/api/battle")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class BattleApi {

    final IBattleService mBattleService;

    @Operation(summary = "查看会战状态")
    @GetMapping("/status/{id}")
    public BattleInfoVo status(
            @Parameter(description = "公会Id", required = true) @PathVariable(name = "id", required = true) Long pUnionId,
            @Parameter(description = "年", required = false) @RequestParam(name = "year", required = false) Integer pYear,
            @Parameter(description = "星座", required = false) @RequestParam(name = "constellation", required = false) EConstellation pEConstellation){
        BattleInfoVo battleInfoVo;
        if(null == pYear && null == pEConstellation){
            battleInfoVo = mBattleService.status(pUnionId);
        }else{
            battleInfoVo = mBattleService.status(pUnionId,pYear,pEConstellation);
        }
        return battleInfoVo;
    }
}

6.6 HitApi

@Api(tags = "3.Hit接口")
@RequestMapping("/api/hit")
@Slf4j
@ZfRestController
@RequiredArgsConstructor
public class HitApi {

    final IHitService mHitService;

    @Operation(summary = "查询刀信息")
    @GetMapping("/info/{id}")
    public HitVo info(@Parameter(description = "刀Id", required = true) @PathVariable(name = "id", required = true) Long pId){
        HitVo hitVo = mHitService.info(pId);
        return hitVo;
    }

    @Operation(summary = "查询刀列表")
    @GetMapping("/list")
    public List<HitVo> listForPlayer(
            @Parameter(description = "战斗Id") @RequestParam(name = "battleId") Long pBattleId,
            @Parameter(description = "玩家Id") @RequestParam(name = "playerId") Long pPlayerId,
            @Parameter(description = "天") @RequestParam(name = "day") Integer pDay){
        List<HitVo> hitVoList = mHitService.listForPlayer(pBattleId,pPlayerId,pDay);
        return hitVoList;
    }

    @Operation(summary = "发送消息-JSON")
    @GetMapping("/page")
    public Page<HitVo> page(
            @Parameter(description = "当前页") @RequestParam(name = "current") int pCurrent,
            @Parameter(description = "页大小") @RequestParam(name = "size") int pSize,
            @Parameter(description = "战斗Id") @RequestParam(name = "battleId") Long pBattleId,
            @Parameter(description = "玩家Id") @RequestParam(name = "playerId") Long pPlayerId,
            @Parameter(description = "公会Id") @RequestParam(name = "unionId") Long pUnionId){
        Page<HitVo> hitVoPage = mHitService.page(pCurrent,pSize,pBattleId,pPlayerId,pUnionId);
        return hitVoPage;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值