mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
feat: overview-stats now work in the frontend
This commit is contained in:
parent
72872b9040
commit
73e40820bd
6 changed files with 41 additions and 34 deletions
|
|
@ -156,7 +156,7 @@
|
||||||
<svg class="w-5 h-5 text-blue-200">
|
<svg class="w-5 h-5 text-blue-200">
|
||||||
<use xlink:href="#stopwatch" />
|
<use xlink:href="#stopwatch" />
|
||||||
</svg>
|
</svg>
|
||||||
<div class="text-lg font-medium text-teal-400">{{ (data.time/1000)|secToTime }}</div>
|
<div class="text-lg font-medium text-teal-400">{{ (data.time)|secToTime }}</div>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div class="text-xs font-medium text-white">{{ data.date }}</div>
|
<div class="text-xs font-medium text-white">{{ data.date }}</div>
|
||||||
|
|
|
||||||
|
|
@ -185,12 +185,12 @@
|
||||||
</div>
|
</div>
|
||||||
<ul class="mt-1 text-gray-100">
|
<ul class="mt-1 text-gray-100">
|
||||||
<li
|
<li
|
||||||
v-for="(championClass, index) in championClasses"
|
v-for="(championClass, index) in stats.class"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{'bg-blue-760': index % 2 !== 0}"
|
:class="{'bg-blue-760': index % 2 !== 0}"
|
||||||
class="flex items-center justify-between px-4 py-1 leading-tight"
|
class="flex items-center justify-between px-4 py-1 leading-tight"
|
||||||
>
|
>
|
||||||
<div class="w-2/4 text-left capitalize">{{ championClass._id }}</div>
|
<div class="w-2/4 text-left capitalize">{{ championClass.id }}</div>
|
||||||
<div
|
<div
|
||||||
:class="calculateWinrate(championClass.wins, championClass.count).color"
|
:class="calculateWinrate(championClass.wins, championClass.count).color"
|
||||||
class="w-1/4"
|
class="w-1/4"
|
||||||
|
|
@ -241,16 +241,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
championClasses() {
|
|
||||||
const classes = [...this.stats.class]
|
|
||||||
return classes.sort((a, b) => b.count - a.count)
|
|
||||||
},
|
|
||||||
mostPlayedRole() {
|
mostPlayedRole() {
|
||||||
return Math.max(...this.stats.role.map(r => r.count), 0)
|
return Math.max(...this.stats.role.map(r => r.count), 0)
|
||||||
},
|
},
|
||||||
globalStatsKeys() {
|
globalStatsKeys() {
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const { _id, wins, losses, count, time, kp, ...rest } = this.stats.global
|
const { id, wins, losses, count, time, kp, ...rest } = this.stats.global
|
||||||
return rest
|
return rest
|
||||||
},
|
},
|
||||||
...mapState({
|
...mapState({
|
||||||
|
|
@ -270,10 +266,9 @@ export default {
|
||||||
leagueStatsByType(typeName) {
|
leagueStatsByType(typeName) {
|
||||||
return this.stats.league
|
return this.stats.league
|
||||||
.map(l => {
|
.map(l => {
|
||||||
return { ...l, ...gameModes[l._id] }
|
return { ...l, ...gameModes[l.id] }
|
||||||
})
|
})
|
||||||
.filter(l => l.type === typeName)
|
.filter(l => l.type === typeName)
|
||||||
.sort((a, b) => b.count - a.count)
|
|
||||||
},
|
},
|
||||||
roundedRoleLosses(win, count) {
|
roundedRoleLosses(win, count) {
|
||||||
return win === count ? 'rounded-full' : 'rounded-b-full'
|
return win === count ? 'rounded-full' : 'rounded-b-full'
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@
|
||||||
class="z-40 sidebar"
|
class="z-40 sidebar"
|
||||||
container-selector=".vue-sticky-container"
|
container-selector=".vue-sticky-container"
|
||||||
>
|
>
|
||||||
<!-- TODO: add it back when implemented -->
|
<SummonerChampions />
|
||||||
<!-- <SummonerChampions />
|
|
||||||
<SummonerStats />
|
<SummonerStats />
|
||||||
<SummonerMates /> -->
|
<!-- TODO: add it back when implemented -->
|
||||||
|
<!-- <SummonerMates /> -->
|
||||||
</VueStickySidebar>
|
</VueStickySidebar>
|
||||||
<div class="w-9/12">
|
<div class="w-9/12">
|
||||||
<div v-if="current && current.participants" class="mb-4">
|
<div v-if="current && current.participants" class="mb-4">
|
||||||
|
|
@ -57,9 +57,9 @@ import LiveMatch from '@/components/Match/LiveMatch.vue'
|
||||||
import LoadingButton from '@/components/Form/LoadingButton.vue'
|
import LoadingButton from '@/components/Form/LoadingButton.vue'
|
||||||
import Match from '@/components/Match/Match.vue'
|
import Match from '@/components/Match/Match.vue'
|
||||||
import OverviewLoader from '@/components/Summoner/Overview/OverviewLoader.vue'
|
import OverviewLoader from '@/components/Summoner/Overview/OverviewLoader.vue'
|
||||||
// import SummonerChampions from '@/components/Summoner/Overview/SummonerChampions.vue'
|
import SummonerChampions from '@/components/Summoner/Overview/SummonerChampions.vue'
|
||||||
// import SummonerMates from '@/components/Summoner/Overview/SummonerMates.vue'
|
// import SummonerMates from '@/components/Summoner/Overview/SummonerMates.vue'
|
||||||
// import SummonerStats from '@/components/Summoner/Overview/SummonerStats.vue'
|
import SummonerStats from '@/components/Summoner/Overview/SummonerStats.vue'
|
||||||
import VueStickySidebar from 'vue-sticky-sidebar'
|
import VueStickySidebar from 'vue-sticky-sidebar'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -68,9 +68,9 @@ export default {
|
||||||
LoadingButton,
|
LoadingButton,
|
||||||
Match,
|
Match,
|
||||||
OverviewLoader,
|
OverviewLoader,
|
||||||
// SummonerChampions,
|
SummonerChampions,
|
||||||
// SummonerMates,
|
// SummonerMates,
|
||||||
// SummonerStats,
|
SummonerStats,
|
||||||
VueStickySidebar
|
VueStickySidebar
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||||
import MatchService from 'App/Services/MatchService'
|
import MatchService from 'App/Services/MatchService'
|
||||||
|
import StatsService from 'App/Services/StatsService'
|
||||||
import MatchesIndexValidator from 'App/Validators/MatchesIndexValidator'
|
import MatchesIndexValidator from 'App/Validators/MatchesIndexValidator'
|
||||||
|
|
||||||
export default class MatchesController {
|
export default class MatchesController {
|
||||||
|
|
@ -12,11 +13,10 @@ export default class MatchesController {
|
||||||
const { puuid, region, matchIds, season } = await request.validate(MatchesIndexValidator)
|
const { puuid, region, matchIds, season } = await request.validate(MatchesIndexValidator)
|
||||||
const matches = await MatchService.getMatches(region, matchIds, puuid)
|
const matches = await MatchService.getMatches(region, matchIds, puuid)
|
||||||
|
|
||||||
// TODO: add Stats here
|
const stats = await StatsService.getSummonerStats(puuid, season)
|
||||||
// const stats = await StatsService.getSummonerStats(puuid, season)
|
|
||||||
return response.json({
|
return response.json({
|
||||||
matches,
|
matches,
|
||||||
stats: 'TODO',
|
stats,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class MatchParser {
|
||||||
region: match.info.platformId.toLowerCase(),
|
region: match.info.platformId.toLowerCase(),
|
||||||
result: match.info.teams[0].win ? match.info.teams[0].teamId : match.info.teams[1].teamId,
|
result: match.info.teams[0].win ? match.info.teams[0].teamId : match.info.teams[1].teamId,
|
||||||
season: getSeasonNumber(match.info.gameCreation),
|
season: getSeasonNumber(match.info.gameCreation),
|
||||||
gameDuration: match.info.gameDuration,
|
gameDuration: Math.round(match.info.gameDuration / 1000),
|
||||||
})
|
})
|
||||||
|
|
||||||
// - 2x MatchTeam : Red and Blue
|
// - 2x MatchTeam : Red and Blue
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,17 @@
|
||||||
import Database from '@ioc:Adonis/Lucid/Database'
|
import Database from '@ioc:Adonis/Lucid/Database'
|
||||||
|
|
||||||
class MatchRepository {
|
class MatchRepository {
|
||||||
|
private readonly JOIN_MATCHES = 'INNER JOIN matches ON matches.id = match_players.match_id'
|
||||||
|
private readonly JOIN_TEAMS =
|
||||||
|
'INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color'
|
||||||
|
private readonly JOIN_ALL = `${this.JOIN_MATCHES} ${this.JOIN_TEAMS}`
|
||||||
|
|
||||||
|
private readonly GLOBAL_FILTERS = `
|
||||||
|
summoner_puuid = :puuid
|
||||||
|
AND match_teams.result != 'Remake'
|
||||||
|
AND matches.gamemode NOT IN (800, 810, 820, 830, 840, 850, 2000, 2010, 2020)
|
||||||
|
`
|
||||||
|
|
||||||
public async globalStats(puuid: string) {
|
public async globalStats(puuid: string) {
|
||||||
const query = `
|
const query = `
|
||||||
SELECT
|
SELECT
|
||||||
|
|
@ -16,10 +27,9 @@ class MatchRepository {
|
||||||
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
||||||
FROM
|
FROM
|
||||||
match_players
|
match_players
|
||||||
INNER JOIN matches ON matches.id = match_players.match_id
|
${this.JOIN_ALL}
|
||||||
INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color
|
|
||||||
WHERE
|
WHERE
|
||||||
summoner_puuid = :puuid
|
${this.GLOBAL_FILTERS}
|
||||||
LIMIT
|
LIMIT
|
||||||
1
|
1
|
||||||
`
|
`
|
||||||
|
|
@ -58,12 +68,13 @@ class MatchRepository {
|
||||||
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
||||||
FROM
|
FROM
|
||||||
match_players
|
match_players
|
||||||
INNER JOIN matches ON matches.id = match_players.match_id
|
${this.JOIN_ALL}
|
||||||
INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color
|
|
||||||
WHERE
|
WHERE
|
||||||
summoner_puuid = :puuid
|
${this.GLOBAL_FILTERS}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
matches.gamemode
|
matches.gamemode
|
||||||
|
ORDER BY
|
||||||
|
count DESC
|
||||||
`
|
`
|
||||||
const { rows } = await Database.rawQuery(query, { puuid })
|
const { rows } = await Database.rawQuery(query, { puuid })
|
||||||
return rows
|
return rows
|
||||||
|
|
@ -78,9 +89,10 @@ class MatchRepository {
|
||||||
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
||||||
FROM
|
FROM
|
||||||
match_players
|
match_players
|
||||||
INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color
|
${this.JOIN_ALL}
|
||||||
WHERE
|
WHERE
|
||||||
summoner_puuid = :puuid
|
${this.GLOBAL_FILTERS}
|
||||||
|
AND match_players.team_position != 0
|
||||||
GROUP BY
|
GROUP BY
|
||||||
role
|
role
|
||||||
`
|
`
|
||||||
|
|
@ -100,13 +112,13 @@ class MatchRepository {
|
||||||
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
||||||
FROM
|
FROM
|
||||||
match_players
|
match_players
|
||||||
INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color
|
${this.JOIN_ALL}
|
||||||
WHERE
|
WHERE
|
||||||
summoner_puuid = :puuid
|
${this.GLOBAL_FILTERS}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
match_players.champion_id
|
match_players.champion_id
|
||||||
ORDER BY
|
ORDER BY
|
||||||
count DESC
|
count DESC, match_players.champion_id
|
||||||
LIMIT
|
LIMIT
|
||||||
:limit
|
:limit
|
||||||
`
|
`
|
||||||
|
|
@ -123,9 +135,9 @@ class MatchRepository {
|
||||||
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
COUNT(case when match_teams.result = 'Fail' then 1 else null end) as losses
|
||||||
FROM
|
FROM
|
||||||
match_players
|
match_players
|
||||||
INNER JOIN match_teams ON match_players.match_id = match_teams.match_id AND match_players.team = match_teams.color
|
${this.JOIN_ALL}
|
||||||
WHERE
|
WHERE
|
||||||
summoner_puuid = :puuid
|
${this.GLOBAL_FILTERS}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
match_players.champion_role
|
match_players.champion_role
|
||||||
ORDER BY
|
ORDER BY
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue