1 Star 0 Fork 1

车站旁的橘子 / 源码文档

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

源码文档

项目架构

项目采用前后端分离模式,使用maven进行项目构建。

项目结构

项目包结构为com.magicbeans.sheer。项目为模块分为sheer-api,sheer-common,sheer-parent,sheer-service,sheer-admin(后台模板),sheer-api为项目入口类。项目运行最低需要java8。项目层次为三层架构,controller层,service层,mapper层,其中mapper采用mybatis-plus为基础的持久层框架。项目特点采用redis进行分布式存储,编码使用stream流,函数式接口,Lambada表达式。

项目详情

个人赛要素:赛程*(List [Query]),房间(key-value)。(homeNo答题房间)

团队赛要素:赛程(List [Query]),房间(key-value)。团战房间(HouseUserVO 团队房间)(homeNo答题房间)

sheer-api入口类

*.sheer.aop

ApiRequestRespect(类):用于计算每个请求的访问时间

.sheer.config(包结构):

public class InitCityConfig:(初始化配置类)

// 实现CommandLineRunner类,springboot定时任务类
public class InitCityConfig extends AbstractInitConfig implements CommandLineRunner
commonService.cacheCity();
//缓存城市,从数据库中查询城市,写入缓存

public class InitNewProvinceRankDataConfig:(初始化机构数据)

//移除缓存中所有的机构
redisService.remove(StatusConstant.COUNT_PROVINCE_NEW);
//查询所有的用户
List<User> users = userService.findList("isValid", 1);
//查询当前用户的关卡数,分数,星数之和,添加排行榜缓存
int star = starRecordService.getAllStar(user.id);
//通过查询用户的邀请码获取当前用户的的所属机构,把当前机构加入到缓存队列中
 redisService.zSetIncrementScore(StatusConstant.COUNT_PROVINCE_NEW, o.id, 0));

public class InitNewProvinceRankDataConfig:(初始化省人数)

// 是否初始化机构人数
redisTemplate.delete(StatusConstant.COUNT_ORGANIZATION_PERSON);
List<Organization> list = organizationService.findList("1", "1");
redisTemplate.opsForValue().set(StatusConstant.COUNT_ORGANIZATION_PERSON, objectMapper.writeValueAsString(list));

public class InitNewProvinceUserConfig:(初始化新的数据)

commonService.cacheNews();
//移除缓存中的机构人数
redisTemplate.delete(StatusConstant.COUNT_ORGANIZATION_PERSON);
//查询机构列表
List<Organization> list = organizationService.findList("1", "1");
//写入缓存
redisTemplate.opsForValue().set(StatusConstant.COUNT_ORGANIZATION_PERSON, objectMapper.writeValueAsString(list));

public class InitNewsConfig:(初始化新闻列表)

// 查询全部新闻
List<News> list = newsService.findAllByOrder();
// 根据新闻类型分别缓存
if (Objects.nonNull(news)) {
    redisTemplate.opsForValue().set(StatusConstant.NEWS_CACHE, JSON.toJSONString(news));
}
if (Objects.nonNull(branch)) {
    redisTemplate.opsForValue().set(StatusConstant.BRANCH_CACHE, JSON.toJSONString(branch));
}

public class InitNoticeConfig:(初始化消息)

commonService.cacheNotice();
// 查询所有公告
List<Notice> list = noticeService.findList("isValid", StatusConstant.YES);
// 缓存公告
redisTemplate.opsForValue().set(StatusConstant.NOTICE_CACHE, noticeStr);

public class InitOrganizationConfig:(初始化机构)

//缓存机构
commonService.cacheOrganization();
//查询机构,建立邀请码与机构对应的map数据
List<Organization> list = organizationService.findList("1", "1");
//移除缓存中不存在的机构,更新机构
redisTemplate.opsForHash().delete(StatusConstant.ORGANIZATION_CACHE, code);
redisTemplate.opsForHash().put(StatusConstant.ORGANIZATION_CACHE, code, JSON.toJSONString(org));

public class InitScheduleConfig:(初始化赛程及分组)

// 查询所有赛程,将赛程列表加入缓存
List<Schedule> schedules = scheduleService.findAll();
cacheUpdateUtil.addScheduleListToCache(schedules);

// 查询团队赛程,根据团队id查询赛程,,更新赛程信息,将团队赛程加入缓存
List<Team> teamList = teamService.findAll();
cacheUpdateUtil.addTeamScheduleListToCache(teamList);

public class InitSubjectConfig:(初始化题库)

//缓存题库到redis
commonService.cacheSubjectToRedis();
// 查询题库
List<Subject> subjects = subjectService.findList("type", 0);
// 查询所有答案
List<SubjectItem> subjectItems = subjectItemService.findList("1", "1");
//题库和答案进行映射 >>> 将题目与关卡进行整合 >>> 将题目存入内存中

public class InitTeamSubjectConfig:(团队题库启动加载)

//缓存题库
commonService.cacheTeamSubjectToRedis();
//查询题库 >>> 查询所有答案 >>> 将答案和题目相匹配 写入缓存

*.sheer.controller(包结构)

public class TeamController:战队赛程

​ public ResponseData mySchedule:查询我的赛程,通过前后文获取用户信息,在通过用户信息获取赛程信息,并返回赛程信息。

User currentUser = LoginHelper.getCurrentUser(redisService);
UserScheduleInfo usi = scheduleService.findMySchedule(currentUser);
// scheduleService.findMySchedule(service层接口)
// 通过查询缓存中的用户信息获取当前用户赛程,并加入赛程列表

public ResponseData historySchedule:查询历史赛程

page = scheduleService.findHistorySchedulePage(page, currentUser);
//通过查询缓存中的历史数据,通过排序分页后返回

KeepAliveController:心跳检测类

​ public ResponseData validate: 接受token,检测用户是否登录

//从redis中获取用户信息
User user = (User) redisService.get(token);

​ public ResponseData houseOnline:接受token,检测房间是否存在

//设置
redisService.set(PollStatusConstants.HOUSE_HEART_DUNCE +
                 user.getToken(), "1", PollStatusConstants.REDIS_POLL_USER_KEEP_ALLIVE_SECONDS, TimeUnit.SECONDS);

//在redis中设置房间缓存key-value     
template.opsForValue().set(key, value, time, timeUnit);

MatchController:匹配请求类

​ public ResponseData start:@param(token,scheduleId) 开始匹配,通过查询redis中的赛程信息,比赛信息。将比赛赛程队列加入到比赛房间缓存。

//比赛匹配 (使用MatchServiceImpl类)
matchService.start(token, scheduleId, u, schedule);
//用户是否已匹配
redisService.get(PollStatusConstants.CANCEL_MATCH_ORDER + token) != null
//获取当前赛程的房间队列集合,当队列为空时,创建新的空列队,并加入到缓存
Object o = redisService.get(PollStatusConstants.TEAM_WAR_ROOMS_PREFIX + scheduleId);    
//再次获取赛程情况,确认用户自己是否在队列中
redisService.set(PollStatusConstants.TEAM_WAR_ROOMS_PREFIX + schedule.getId(), queues, seconds, TimeUnit.SECONDS);
redisService.get(PollStatusConstants.MATCHED_SUCCESS_INFO_PREFIX + u.getId()) == null
//用户加入队列,赛程队列加入到房间缓存
queueList.get(0).offer(u.getToken());
redisService.set(PollStatusConstants.TEAM_WAR_ROOMS_PREFIX + schedule.getId(), queueList);
//从对方战队取出用户进行匹配,更新房间缓存
matchUser = (User) redisService.get((frontQueue.poll()));
//匹配成功后的处理(当前用户,对象用户,赛程队列,赛程)
executeMatchSuccess(u, matchUser, queueList, schedule);
//创建一个对战房间,缓存房间题目,换成匹配对象(双方当用户,对战房间,过期时间)
redisService.addList(PollStatusConstants.TEAM_HOUSE_SUBJECT_PREFIX + homeNo, subject);
redisService.set(PollStatusConstants.MATCHED_SUCCESS_INFO_PREFIX + matchUser.getId(), msi, PollStatusConstants.MATCH_SUCCESS_WAIT_TIME, TimeUnit.SECONDS);
//在队列中添加对战双方对象
redisService.addList(homeNo, currentUser);
redisService.addList(homeNo, matchUser);
//设置第一道题目开始时间
teamService.setHomeSubjectStartTime(msi.getHomeNo(), msi.getSubjectList().get(0).getId());
//创建比赛结果实体类返回前端,设置对战房间失效时间

​ public ResponseData cacel:@param(token,scheduleId) 取消匹配,

//取消匹配(用户,赛程)
matchService.cacelMatch(u, schedule);
//取出赛程队列,判断用户方向,根据用户方向判断用户是否在队列存在
List<Queue> queueList = (List<Queue>) redisService.get(PollStatusConstants.TEAM_WAR_ROOMS_PREFIX + schedule.getId());
Queue queue = userIsA(u, schedule) ? queueList.get(0) : queueList.get(1);
//判断用户是否已经匹配成功,匹配成功则无法取消匹配
MatchSuccessInfo msi = (MatchSuccessInfo) redisService.get(PollStatusConstants.MATCHED_SUCCESS_INFO_PREFIX + u.getId());

​ public ResponseData getCurrentGameInfo:@param(token,scheduleId) 团战等待界面信息。查询redis中用户是否登录,比赛开始结束情况。

//等待团战信息(用户,赛程)
matchService.currentGameInfo(u, schedule);
//创建两个房间列表
List<HouseUserVO> myTeamUserList = new ArrayList<>();
List<HouseUserVO> frontTeamUserList = new ArrayList<>();
//从缓存中取出团战队伍列表,遍历添加到房间列表中
List<Object> teamUserListA = redisService.getList(PollStatusConstants.ST + schedule.getId() + "_" + schedule.getFirstTeamId());
List<Object> teamUserListB = redisService.getList(PollStatusConstants.ST + schedule.getId() + "_" + schedule.getSecondTeamId());

for (Object o : teamUserListA) {
    HouseUserVO o1 = (HouseUserVO) o;
    if (userIsA(u, schedule)) {
        myTeamUserList.add(o1);
    } else {
        frontTeamUserList.add(o1);
    }
}
for (Object o : teamUserListB) {
    HouseUserVO o1 = (HouseUserVO) o;
    if (userIsA(u, schedule)) {
        frontTeamUserList.add(o1);
    } else {
        myTeamUserList.add(o1);
    }
}
//创建对战页面玩家信息实体,过滤重复用户
filterDuplicateUser(myTeamUserList);
//将自身加入房间放入缓存
updateTeamRoomOnlineUser(u, schedule.getFirstTeamId(), schedule);

​ public ResponseData getLastTime:@param(scheduleId) 获取比赛的剩余时间,通过比赛id查询当前比赛的剩余时间,返回比赛剩余时间

long lastSeconds = PollStatusConstants.TEAM_TIME_MINUTES * 60 - ((new Date().getTime() - schedule.getStartTime().getTime()) / 1000);

​ public ResponseData lossMatch:@param(token,scheduleId)未匹配对手记录。用户和赛程查询比赛房间情况,查询所有团队赛程房间情况

//从缓存中获取用户,获取房间列表
User u = (User) redisService.get(token);
List<Object> houseUserVOS = redisService.getList(PollStatusConstants.ST + scheduleId + "_" + u.getTeamId());
//从缓存中获取房间列表
for (Object o : houseUserVOS) {
    HouseUserVO huv = (HouseUserVO) o;
    if (huv.getId().equals(u.getId())) {
        redisService.removeList(PollStatusConstants.ST + scheduleId + "_" + u.getTeamId(), huv);
        huv.setTimeOuts(huv.getTimeOuts() + 1);
        redisService.addList(PollStatusConstants.ST + scheduleId + "_" + u.getTeamId(), huv);
        this.redisService.set(PollStatusConstants.TEAM_MATCH_TIMEOUTS_PREFIX + token, PollStatusConstants.TEAM_MATCH_TIMEOUTS_PREFIX + token, 35L, TimeUnit.SECONDS);
        break;
    }
}

TeamWarController:团队战

​ public ResponseData answer:答题,获取房间列表,查询房间是否存在当前用户。获取题目和答案,判断是否事最后一题,最后一题分数加倍。更具题目计算答案,并把已完成的答题情况写入缓存。最后创建一个新的队伍答题实例,返回前端。

//检查房间的用户数据,判断用户是否存在。获取当前房间的题目和答案列表,获取答题数量,计算答题分数。把答题得分加入到缓存,设置答题题目答案集缓存过期时间
TeamUserAnswer teamUserAnswer = this.teamService.answer(scheduleId, teamId, userId, subjectId, answerId, homeNo, userTime);

​ public ResponseData answerTimeout:答题超时,返回一个新的答题实例。

//超时提交
TeamUserAnswer teamUserAnswer = this.teamService.answerTimeout(scheduleId, teamId, userId, subjectId, homeNo);

​ public ResponseData isNext:进入下一题,判断双方事否完成答题

//能否进入下一题
//获取房间的用户数据,获取对象答题情况
Map map = this.teamService.subjectNext(scheduleId, teamId, homeNo, userId, subjectId, nextSubjectId);

​ public ResponseData userScore:本轮结果

//获取本轮答题结果
// 查询用户是否都完成了答题,完成答题后进行数据持久化
List<TeamUserGameVO> list = this.teamService.userScore(scheduleId, teamId, homeNo, userId);

​ public ResponseData score:团战结果

//团战结果
//从缓存中存取,没有缓存则从数据库查询,数据库未查询到,统计分数
TeamWarScoreVO teamWarScoreVO = this.teamService.teamScore(scheduleId, teamId);

​ public ResponseData scheduleHistoryScore:历史赛程详情

//先查缓存,缓存无则查询数据库
TeamWarScoreVO teamWarScoreVO = this.teamService.scheduleHistoryScore(scheduleId, teamId);

语法详情

CommandLineRunner

是springboot的在项目启动后的回调接口,只要实现接口,即可时间功能运行。类似与开机自启动。同ApplicationRunner一样的效果。

public interface CommandLineRunner {
    void run(String... var1) throws Exception;
}

redisTemplate

spring针对redis进行封装,提供了一个redisTemplate的类,主要可以操作。在使用redis操作中必须进行序列化操作/反序列化操作。

  • ValueOperations:简单K-V操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对map类型的数据操作
  • ListOperations:针对list类型的数据操作
@Autowired
private RedisTemplate redisTemplate;

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/people_money/source-document.git
git@gitee.com:people_money/source-document.git
people_money
source-document
源码文档
master

搜索帮助