Spring Boot 8 实现对战记录(次要)&&用户分数排行榜(次要)&&实现分页(重点(1)

最后

光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性

Java面试宝典2021版

最常见Java面试题解析(2021最新版)

2021企业Java面试题精选

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

	- [2.3.实现查看录像功能](#23_235)
	- [2.4.(重点)实现对战记录的分页功能\_前端(后端已经在【\*】处实现)](#24__468)
	- [2.5.后端排行榜的分页功能(后端+前端)](#25_576)
	- * + [5.1后端](#51_577)
	- [2.6.给Bot数量加上限制](#26Bot_720)

1.上次收尾工作

游戏结束更新积分
userMapper修改为public,因为要在对局结束,修改玩家积分
在这里插入图片描述
在这里插入图片描述

2.主要内容

2.1加上mybatis分页配置
package com.kob.backend.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}


2.2对局列表和回放

在类内定义属性时,使用spring自动注入的话,若是在service或controller定义,则不用定义static。翻译过来,意思就是,若当前类本身是单例,则属性本身就只会有一份,无论加不加静态变量,效果都一样;若是第三方类,也就是自己写的类,一般都是会定义多个对象,那么就要思考属性到底是属于类的,还是属于对象的。

A: 后端(实现返回对战记录列表)【*】

接口

package com.kob.backend.service.record;

import com.alibaba.fastjson.JSONObject;

public interface GetRecordListService {
    public JSONObject getList(Integer page);//传入第几页,返回JSONObject
}


实现接口

package com.kob.backend.service.impl.record;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kob.backend.mapper.RecordMapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.Record;
import com.kob.backend.pojo.User;
import com.kob.backend.service.record.GetRecordListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class GetRecordListServiceImpl implements GetRecordListService {
    @Autowired
    private RecordMapper recordMapper ;
    @Autowired
    private UserMapper userMapper;

    @Override
    public JSONObject getList(Integer page) {
        IPage<Record> recordIPage = new Page<>(page,10);//API
        QueryWrapper<Record> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");//按照降序排列
        List<Record> records = recordMapper.selectPage(recordIPage,queryWrapper).getRecords();//一页
        JSONObject resp = new JSONObject();
        List<JSONObject> items = new ArrayList<>();
        for(Record record:records){
            User userA = userMapper.selectById(record.getAId());
            User userB = userMapper.selectById(record.getBId());
            JSONObject item = new JSONObject();
            item.put("a\_photo",userA.getPhoto());
            item.put("a\_username",userA.getUsername());
            item.put("b\_photo",userB.getPhoto());
            item.put("b\_username",userB.getUsername());
            item.put("record",record);
            items.add(item);
        }
        resp.put("records",items);
        resp.put("records\_count",recordMapper.selectCount(null));
        return resp;
    }
}


控制器

package com.kob.backend.controller.record;

import com.alibaba.fastjson.JSONObject;
import com.kob.backend.service.record.GetRecordListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
public class GetRecordListController {
    @Autowired
    private GetRecordListService getRecordListService;

    @GetMapping("/record/getlist/")
    public JSONObject getList(@RequestParam Map<String,String> data){
        Integer page = Integer.parseInt(data.get("page"));
        return getRecordListService.getList(page);
    }
}


B: 前端(实现接收展示对战记录列表)

查询一下后端数据
将列表显示出来
展示table,把之前的table复制过来即可

<template>
    <ContentField>
    <div class="container">
        <div class="row">   
            <div class="card-body">
        <table class="table table-striped table-hover">
            <!-- 表头 -->
            <thead>
                <tr>
                    <th>A</th>
                    <th>B</th>
                    <th>对战结果</th>
                    <th>对战时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <!-- 表身 -->
            <tbody>
                <tr v-for="record in records" :key="record.record.id">
                    <th>
                        <img :src="record.a\_photo" alt="" class="record-user-photo">&nbsp;
                        {{record.a_username}}
                    </th>
                    <th>
                        <img :src="record.b\_photo" alt="" class="record-user-photo">&nbsp;
                        {{record.b_username}}
                    </th>
                    <th>
                        {{record.result}}
                    </th>
                    <th>
                        {{record.record.createtime}}
                    </th>
                    <th>
                        <button type="button" class="btn btn-secondary">查看录像</button>
                    </th>
                </tr>
            </tbody>
        </table>
            </div> 
        </div>
    </div>
    </ContentField>
</template>

<script>
import ContentField from "@/components/ContentField"
import $ from "jquery"
import { useStore } from "vuex"
import { ref } from "vue"

export default {
    components:{
        ContentField
    },
    setup(){
        const store = useStore();
        let total_records = 0 ;
        let current_page = 1 ;
        let records = ref([]);
        console.log("total\_records:" + total_records, " current\_page:" + current_page)
        const pull_page = page =>{
            current_page = page ;
            $.ajax({
                url:"http://localhost:3000/record/getlist/",
                type:"get",
                data:{
                    page,
                },
                headers:{
                  Authorization:"Bearer " + store.state.user.token,
                },
                success(resp){
                    records.value = resp.records ;
                    total_records = resp.records_count ;
                },
                error(resp){
                    console.log(resp)
                }
            })
        }

        pull\_page(current_page);

        return {
            records,            
        }
    }
}
</script>

<style scoped>
img.record-user-photo {
    width: 5vh;
    border-radius: 50% ;
}
</style>

在这里插入图片描述

2.3.实现查看录像功能

点击后跳转页面,需要写一个新的View
直接将pk界面复制过来,需要判断是录像还是对战
只需要一个PlayGround组件就可以了
把页面加到路由里面点开Router加一个路由

store/record.js

// import $ from "jquery"

export default {
  state: {
    is_record : false ,
    a_steps:"",
    b_steps:"",
    record_loser:"",
  },
  getters: {
  },
  mutations: {
    updateIsRecord(state,is_record){
        state.is_record = is_record;
    },
    updateSteps(state,data){
      state.a_steps = data.a_steps;
      state.b_steps = data.b_steps;
    },
    updateRecordLoser(state,loser){
      state.record_loser = loser ;
    }
  },
  actions: {
  },
  modules: {
  }
}


RecordIndexView.vue

<template>
    <ContentField>
        <table class="table table-striped table-hover">
            <!-- 表头 -->
            <thead>
                <tr>
                    <th>A</th>
                    <th>B</th>
                    <th>对战结果</th>
                    <th>对战时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <!-- 表身 -->
            <tbody>
                <tr v-for="record in records" :key="record.record.id">
                     <td>
                        <img :src="record.a\_photo" alt="" class="record-user-photo">
                        &nbsp;
                        <span class="record-user-username">{{ record.a_username }}</span>
                    </td>
                    <td>
                        <img :src="record.b\_photo" alt="" class="record-user-photo">
                        &nbsp;
                        <span class="record-user-username">{{ record.b_username }}</span>
                    </td>
                    <td>{{ record.result }}</td>
                    <td>{{ record.record.createtime }}</td>
                    <td>
                        <button @click="open\_record\_content(record.record.id)" type="button" class="btn btn-secondary">查看录像</button>
                    </td>
                </tr>
            </tbody>
        </table>
    </ContentField>
</template>

<script>
import ContentField from "@/components/ContentField"
import $ from "jquery"
import { useStore } from "vuex"
import { ref } from "vue"
import router from "@/router/index"
export default {
    components:{
        ContentField
    },
    setup(){
        const store = useStore();
        let total_records = 0 ;
        let current_page = 1 ;
        let records = ref([]);
        console.log("total\_records:" + total_records, " current\_page:" + current_page)
        const pull\_page = page =>{
            current_page = page ;
            $.ajax({
                url:"http://127.0.0.1:3000/record/getlist/",
                type:"get",
                data:{
                    page,
                },
                headers:{
                  Authorization:"Bearer " + store.state.user.token,
                },
                success(resp){
                    console.log("&&&&&&&&&&&&&")
                    records.value = resp.records ;
                    total_records = resp.records_count ;
                },
                error(resp){
                    console.log(resp)
                }
            })
        }

        pull\_page(current_page);

        const stringTo2D = map =>{
              let g = [] ;
              for(let i = 0,k = 0;i < 13 ;i ++ ){
                let line = [];
                for(let j = 0 ;j < 14 ;j++){
                    if(map[k] === '0')line.push(0);
                    else line.push(1);
                    k++;
                }
                g.push(line);
              }  
              return g ;
        }

        const open\_record\_content = recordId => {
            for(const record of records.value){
                
                if(record.record.id === recordId){
                    console.log(record)
                    store.commit("updateIsRecord",true);
                    store.commit("updateGame",{
                        map:stringTo2D(record.record.map),
                        a\_id:record.record.aid,
                        a\_sx:record.record.asx,
                        a\_sy:record.record.asy,
                        b\_id:record.record.bid,
                        b\_sx:record.record.bsx,
                        b\_sy:record.record.bsy,
                    });
                    store.commit("updateSteps",{
                        a\_steps : record.record.asteps,
                        b\_steps : record.record.bsteps,
                    });
                    console.log(record.record.map,stringTo2D(record.record.map))
                    store.commit("updateRecordLoser",record.record.loser);

                    router.push({
                        name:"record\_content",
                        params:{
                            recordId:recordId,//path中的参数,在router中
                        }
                    })
                    break;
                }
            }
        }

        return {
            records,          
            open_record_content,  
        }
    }
}
</script>

<style scoped>
img.record-user-photo {
    width: 5vh;
    border-radius: 50% ;
}
</style>

Gamemap.js

    //获取键盘输入
    add\_listening\_events(){
       
        if(this.store.state.record.is_record){//record
            let k = 0 ;//第k步
            const [snake0, snake1] = this.snakes ;
            const a_steps = this.store.state.record.a_steps ;
            const b_steps = this.store.state.record.b_steps ;
            console.log(this.store.state.record) ;
            const loser = this.store.state.record.record_loser ;

            const interval_id = setInterval(()=>{
                if(k >= a_steps.length - 1){
                    if(loser === "all" || loser === "A"){
                        snake0.status = "die";
                    }
                    if(loser === "all" || loser === "B"){
                        snake1.status = "die";
                    }  
                    clearInterval(interval_id);
                } else {
                    snake0.set\_direction(parseInt(a_steps[k]));
                    snake1.set\_direction(parseInt(b_steps[k]));
                }
                k ++ ;
            },300)

        }
        else//PK
        {


### 最后

> **针对以上面试题,小编已经把面试题+答案整理好了**
>

![最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo](https://img-blog.csdnimg.cn/img_convert/4e933d6169882a12ab36f6cb18dbc85b.webp?x-oss-process=image/format,png)

![最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo](https://img-blog.csdnimg.cn/img_convert/8d0853e0d26a93bd3c4031bb2644c28c.webp?x-oss-process=image/format,png)

![最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo](https://img-blog.csdnimg.cn/img_convert/fa59891c1675b1a059de2c7819f351e9.webp?x-oss-process=image/format,png)

# 面试专题

![image](https://img-blog.csdnimg.cn/img_convert/c4815979bd45d2002b7b22e6e05b9e6b.webp?x-oss-process=image/format,png)

**除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习**

![image](https://img-blog.csdnimg.cn/img_convert/19dcd63cd836798b61d8023508530f6f.webp?x-oss-process=image/format,png)

![image](https://img-blog.csdnimg.cn/img_convert/27b6f178da0573a81b6448a107f9655f.webp?x-oss-process=image/format,png)

 ![image](https://img-blog.csdnimg.cn/img_convert/f42f83d086466573b4938c2f38df728a.webp?x-oss-process=image/format,png)

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

64022464)]

[外链图片转存中...(img-0HzRe3J1-1715464022465)]

[外链图片转存中...(img-7b3hK3mX-1715464022465)]

# 面试专题

[外链图片转存中...(img-5y7fOrnG-1715464022465)]

**除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习**

[外链图片转存中...(img-RF6fQqUi-1715464022466)]

[外链图片转存中...(img-qQGN5sCb-1715464022466)]

 [外链图片转存中...(img-sQS5UKJ3-1715464022466)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值