Browse Source

rc 0.0.0.1.488

master
gsd 1 month ago
parent
commit
98ab5dfc4a
  1. 7
      src/app/app-routing.module.ts
  2. 12
      src/app/app.module.ts
  3. 14
      src/app/entities/KillFeed.ts
  4. 26
      src/app/entities/Report.ts
  5. 30
      src/app/entities/search/KillFeedSearchFilter.ts
  6. 8
      src/app/pages/banlist-page/banlist-search-table.ts
  7. 8
      src/app/pages/internal-components/DonateSearchTable.ts
  8. 3
      src/app/pages/internal-components/abstract-search-table.component.ts
  9. 29
      src/app/pages/internal-components/search-filters/FilterMatChipKillFeed.ts
  10. 166
      src/app/pages/killfeed-page/KillFeedSearchTable.ts
  11. 0
      src/app/pages/killfeed-page/killfeed-page.component.scss
  12. 28
      src/app/pages/killfeed-page/killfeed-page.component.ts
  13. 2
      src/app/pages/main-page/main-page.component.html
  14. 6
      src/app/pages/main-page/main-page.component.ts
  15. 8
      src/app/pages/messages-page/message-search-table.ts
  16. 30
      src/app/pages/profile-page/profile-page.component.html
  17. 168
      src/app/pages/reports-page/ReportSearchTable.ts
  18. 0
      src/app/pages/reports-page/reports-page.component.scss
  19. 28
      src/app/pages/reports-page/reports-page.component.ts
  20. 56
      src/app/pages/statistic-page/statistic-page.component.html
  21. 5
      src/app/pages/statistic-page/statistic-page.component.ts
  22. 8
      src/app/pages/vip-page/vip-page.component.html
  23. 4
      src/app/pages/vip-page/vip-page.component.ts
  24. 15
      src/app/services/server.service.ts

7
src/app/app-routing.module.ts

@ -10,6 +10,8 @@ import {VipPageComponent} from "./pages/vip-page/vip-page.component";
import {DowngamePageComponent} from "./pages/downgame-page/downgame-page.component";
import {StatisticPageComponent} from "./pages/statistic-page/statistic-page.component";
import {AboutPageComponent} from "./pages/about-page/about-page.component";
import {KillfeedPageComponent} from "./pages/killfeed-page/killfeed-page.component";
import {ReportsPageComponent} from "./pages/reports-page/reports-page.component";
const routes: Routes = [
{ path: "", component: MainPageComponent},
@ -20,8 +22,9 @@ const routes: Routes = [
{ path: "messages", component: MessagesPageComponent },
{ path: "vip", component: VipPageComponent },
{ path: "putisRun", component: DowngamePageComponent },
{ path: "statistic", component: StatisticPageComponent },
{ path: "about", component: AboutPageComponent }
{ path: "reports", component: ReportsPageComponent },
{ path: "about", component: AboutPageComponent },
{ path: "killfeed", component: KillfeedPageComponent }
];
@NgModule({

12
src/app/app.module.ts

@ -70,6 +70,11 @@ import { DowngamePageComponent } from './pages/downgame-page/downgame-page.compo
import { StatisticPageComponent } from './pages/statistic-page/statistic-page.component';
import {DonateSearchTable} from "./pages/internal-components/DonateSearchTable";
import { AboutPageComponent } from './pages/about-page/about-page.component';
import { KillfeedPageComponent } from './pages/killfeed-page/killfeed-page.component';
import {KillFeedSearchTable} from "./pages/killfeed-page/KillFeedSearchTable";
import {FilterMatChipKillFeed} from "./pages/internal-components/search-filters/FilterMatChipKillFeed";
import { ReportsPageComponent } from './pages/reports-page/reports-page.component';
import {ReportSearchTable} from "./pages/reports-page/ReportSearchTable";
registerLocaleData(localeRu, "ru")
@ -91,6 +96,8 @@ registerLocaleData(localeRu, "ru")
BanlistSearchTable,
AnnoncesListCarules,
DonateSearchTable,
KillFeedSearchTable,
ReportSearchTable,
//search filters
FilterMatChipAccount,
FilterMatChipMessage,
@ -100,6 +107,7 @@ registerLocaleData(localeRu, "ru")
FilterMatChipBanId,
FilterMatChipActiveBan,
FilterMatChipAdmins,
FilterMatChipKillFeed,
//dialogs
BanViewDialog,
NewsViewDialog,
@ -109,7 +117,9 @@ registerLocaleData(localeRu, "ru")
VipPromocodeDialog,
DowngamePageComponent,
StatisticPageComponent,
AboutPageComponent
AboutPageComponent,
KillfeedPageComponent,
ReportsPageComponent
],
imports: [
BrowserModule,

14
src/app/entities/KillFeed.ts

@ -0,0 +1,14 @@
export class KillFeed {
id!:number;
attacker_id!:number;
attacker_name!:string;
victim_id!:number;
victim_name!:string;
assister_id!:number;
assister_name!:number;
utime!:number;
weapon_name!:string;
weapon_classname!:string;
server_id!: string;
serverName!: string;
}

26
src/app/entities/Report.ts

@ -0,0 +1,26 @@
import {SteamIDs} from "./profile/SteamIDs";
export class Report {
id!:number;
a_nickname!:string;
a_permition!:string;
a_kills!:number;
a_deads!:number;
a_seconds!:number;
//
r_nickname!:string;
r_permition!:string;
r_kills!:number;
r_deads!:number;
r_seconds!:number;
//
reasons!: string;
utime!:number;
srv!:string;
online!:number;
type!:string;
actions:string[] = []
a_steam!:SteamIDs;
r_steam!:SteamIDs;
serverName!:string;
}

30
src/app/entities/search/KillFeedSearchFilter.ts

@ -0,0 +1,30 @@
import {SearchFilter} from "./SearchFilter";
import {MatPaginator} from "@angular/material/paginator";
import {ParamMap} from "@angular/router";
export class KillFeedSearchFilter extends SearchFilter {
mode:string = 'kills';
override createQuery(paginator:MatPaginator|undefined): { [p: string]: any } {
let q:{[param: string]: any} = super.createQuery(paginator);
q["mode"] = this.mode;
return q;
}
override fromQuery(param: ParamMap,paginator:MatPaginator|undefined) {
try {if (param.get("mode")) { // @ts-ignore
this.mode = param.get("mode");}}catch (e) {}
super.fromQuery(param, paginator);
}
addModeToSearch(mode:string) {
this.mode = mode;
this.updated = true;
}
removeModeFromSearch() {
this.mode = 'kills';
this.updated = true;
}
}

8
src/app/pages/banlist-page/banlist-search-table.ts

@ -152,6 +152,7 @@ export class BanlistSearchTable extends AbstractSearchTable<Ban, BanSearchFilter
}
override updateData() {
if (this.lazy) return;
super.updateData();
this.getBanList();
}
@ -178,4 +179,11 @@ export class BanlistSearchTable extends AbstractSearchTable<Ban, BanSearchFilter
this.filter.updated = true;
}
lazyInit() {
if (this.lazy) {
this.lazy = false;
this.updateData();
}
}
}

8
src/app/pages/internal-components/DonateSearchTable.ts

@ -119,6 +119,7 @@ export class DonateSearchTable extends AbstractSearchTable<DonateStat, SearchFil
}
override updateData() {
if (this.lazy) return;
super.updateData();
this.getDonateStat();
}
@ -128,4 +129,11 @@ export class DonateSearchTable extends AbstractSearchTable<DonateStat, SearchFil
if (amount <= 24 * 60 * 60) return `${amount/60} минут`;
else return `${amount/(24 * 60 * 60)} день`;
}
lazyInit() {
if (this.lazy) {
this.lazy = false;
this.updateData();
}
}
}

3
src/app/pages/internal-components/abstract-search-table.component.ts

@ -27,6 +27,9 @@ export abstract class AbstractSearchTable<T,U extends SearchFilter> implements A
@Input("use_query")
use_query: boolean = true;
@Input("lazy")
lazy: boolean = false;
protected constructor(public authService: AuthService,
protected serverService: ServerService,
protected playerService: PlayerService,

29
src/app/pages/internal-components/search-filters/FilterMatChipKillFeed.ts

@ -0,0 +1,29 @@
import {Component, Input} from "@angular/core";
import {KillFeedSearchFilter} from "../../../entities/search/KillFeedSearchFilter";
@Component({
selector: "app-filter-mat-chip-killfeed",
template: `
<mat-chip
*ngIf="filter && filter.mode!=null"
[matMenuTriggerFor]="killfeedSelect">Искать: {{getFancy(filter.mode)}}
<mat-menu #killfeedSelect>
<button mat-menu-item *ngFor="let t of types" (click)="filter.addModeToSearch(t)">{{getFancy(t)}}</button>
</mat-menu>
</mat-chip>
`
})
export class FilterMatChipKillFeed {
@Input("filter")
filter: KillFeedSearchFilter|undefined;
types:string[] = ['kills','deads','assists'];
getFancy(text:string):string {
switch (text) {
case "kills": return 'по убийствам';
case "assists": return 'по помощи';
case "deads": return 'по смертям';
default: return '';
}
}
}

166
src/app/pages/killfeed-page/KillFeedSearchTable.ts

@ -0,0 +1,166 @@
import {AbstractSearchTable} from "../internal-components/abstract-search-table.component";
import {SearchFilter} from "../../entities/search/SearchFilter";
import {AuthService} from "../../services/auth.service";
import {ServerService} from "../../services/server.service";
import {PlayerService} from "../../services/player.service";
import {ActivatedRoute, Router} from "@angular/router";
import {VipService} from "../../services/vip.service";
import {HttpClient} from "@angular/common/http";
import {map} from "rxjs";
import {PagingAndSortingPaginator} from "../../entities/PagingAndSortingPaginator";
import {KillFeedSearchFilter} from "../../entities/search/KillFeedSearchFilter";
import {KillFeed} from "../../entities/KillFeed";
import {MatTableDataSource} from "@angular/material/table";
import {Component} from "@angular/core";
@Component({
selector: 'app-killfeed-search-table',
template: `
<div style="padding-bottom: 10px;">
<mat-chip-list>
<mat-chip [matMenuTriggerFor]="addFilter">Искать по...</mat-chip>
<mat-menu #addFilter>
<button mat-menu-item (click)="filter.addAccountToSearch('')" [disabled]="account_id!=null">Профилю</button>
<button mat-menu-item [matMenuTriggerFor]="timeSelect">Времени</button>
</mat-menu>
<mat-menu #timeSelect>
<button mat-menu-item (click)="filter.addEndTimeToSearch()">До ...</button>
<button mat-menu-item (click)="filter.addBeginTimeToSearch()">После ...</button>
</mat-menu>
<mat-chip *ngIf="filter.updated" (click)="updateData()">Обновить</mat-chip>
<app-filter-mat-chip-killfeed
[filter]="filter">
</app-filter-mat-chip-killfeed>
<app-filter-mat-chip-account
[filter]="filter"
[hidden]="account_id!=null"
></app-filter-mat-chip-account>
<app-filter-mat-chip-date-begin
[filter]="filter">
</app-filter-mat-chip-date-begin>
<app-filter-mat-chip-date-end
[filter]="filter">
</app-filter-mat-chip-date-end>
</mat-chip-list>
</div>
<div>
<div class="loading-shade"
*ngIf="loading || err">
<mat-spinner *ngIf="loading"></mat-spinner>
<div class="err" *ngIf="err">
Слишком много запросов или сервер не отвечает, обнови страницу.
<br>
<button mat-button (click)="err=false; loading=false">Закрыть</button>
</div>
</div>
<table mat-table [dataSource]="dataSource" style="width: 100%">
<ng-container matColumnDef="attacker_name">
<th mat-header-cell *matHeaderCellDef> Убийца </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="row.attacker_name?aMenu:null"> {{row.attacker_name}}
<mat-menu #aMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.attacker_name)" [disabled]="!row.attacker_name || account_id != null">Добавить в поиск</button>
<button mat-menu-item (click)="filter.addAccountToSearch('[U:1:'+row.attacker_id+']')" [disabled]="account_id != null">Добавить в поиск используя ID</button>
<button mat-menu-item (click)="authService.searchPlayer(row.attacker_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="assister_name">
<th mat-header-cell *matHeaderCellDef> Помог </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="row.assister_name?asMenu:null"> {{row.assister_name}}
<mat-menu #asMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.assister_name)" [disabled]="!row.assister_name || account_id != null">Добавить в поиск</button>
<button mat-menu-item (click)="filter.addAccountToSearch('[U:1:'+row.assister_id+']')" [disabled]="account_id != null">Добавить в поиск используя ID</button>
<button mat-menu-item (click)="authService.searchPlayer(row.assister_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="victim_name">
<th mat-header-cell *matHeaderCellDef> Умер </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="row.victim_name?vMenu:null"> {{row.victim_name}}
<mat-menu #vMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.victim_name)" [disabled]="!row.victim_name || account_id != null">Добавить в поиск</button>
<button mat-menu-item (click)="filter.addAccountToSearch('[U:1:'+row.victim_id+']')" [disabled]="account_id != null">Добавить в поиск используя ID</button>
<button mat-menu-item (click)="authService.searchPlayer(row.victim_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef> Время </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="dateMenu"> {{row.utime * 1000 | date:"HH:mm dd/MM/yyyy"}}
<mat-menu #dateMenu>
<button mat-menu-item (click)="filter.addEndTimeToSearch(row.timestamp * 1000)">Искать до {{row.timestamp * 1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
<button mat-menu-item (click)="filter.addBeginTimeToSearch(row.timestamp * 1000)">Искать после {{row.timestamp * 1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="weapon">
<th mat-header-cell *matHeaderCellDef>Оружие</th>
<td mat-cell *matCellDef="let row"> {{row.weapon_name}}</td>
</ng-container>
<ng-container matColumnDef="server">
<th mat-header-cell *matHeaderCellDef> Сервер </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="serverMenu"> {{row.serverName}}
<mat-menu #serverMenu>
<button mat-menu-item (click)="filter.addServerToSearch(row.server_id)">Добавить в поиск</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- Row shown when there is no matching data. -->
<div *ngIf="!loading">
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">А вот и такое бывает...</td>
</tr>
</div>
</table>
<mat-paginator
[pageSizeOptions]="[5, 10, 25, 100]"
[pageSize]="10"
(page)="updateData()"
></mat-paginator>
</div>
`
})
export class KillFeedSearchTable extends AbstractSearchTable<KillFeedSearchTable, KillFeedSearchFilter> {
displayedColumns: string[] = ['attacker_name', 'assister_name', 'victim_name', 'date', 'weapon', 'server'];
constructor(authService: AuthService,
serverService: ServerService,
playerService: PlayerService,
router: Router,
route: ActivatedRoute,
private http: HttpClient) {
super(authService, serverService, playerService, route, router);
super.filter = new KillFeedSearchFilter();
}
private getStat() {
this.filter.updated = false;
this.loading = true;
this.http.post(`api/profile/killfeed`, this.filter,
{params:
{size: this.paginator?this.paginator.pageSize:20,
page: this.paginator?this.paginator.pageIndex:0,
mode: this.filter.mode }
}).pipe((map((res) => PagingAndSortingPaginator<KillFeed>.newObj().fromData(res).updatePaginator(this.paginator))))
.subscribe((res) => {
this.dataSource = new MatTableDataSource<KillFeedSearchTable>(res.data);
this.err = false;
}, (e) => this.err = true, () => this.loading = false
)
}
override updateData() {
if (this.lazy) return;
super.updateData();
this.getStat();
}
lazyInit() {
if (this.lazy) {
this.lazy = false;
this.updateData();
}
}
}

0
src/app/pages/killfeed-page/killfeed-page.component.scss

28
src/app/pages/killfeed-page/killfeed-page.component.ts

@ -0,0 +1,28 @@
import { Component, OnInit } from '@angular/core';
import {AuthService} from "../../services/auth.service";
@Component({
selector: 'app-killfeed-page',
styleUrls: ['./killfeed-page.component.scss'],
template: `
<div class="content-in-center-header" style="flex-direction: column;">
<h1>История убийств</h1>
<h3>Всегда приятно узнать сколько тебя раз попустил мгебраток</h3>
</div>
<div class="content-in-center">
<div class="content-in-border">
<app-need-auth-to-continue *ngIf="!authService.isAuth()"></app-need-auth-to-continue>
<app-killfeed-search-table *ngIf="authService.isAuth()"></app-killfeed-search-table>
</div>
</div>
`
})
export class KillfeedPageComponent implements OnInit {
constructor(public authService: AuthService) { }
ngOnInit(): void {
}
}

2
src/app/pages/main-page/main-page.component.html

@ -75,3 +75,5 @@
<app-annonces-list-carules [use_query]="false" type="reason4play"></app-annonces-list-carules>
</div>
</div>
<app-statistic-page></app-statistic-page>

6
src/app/pages/main-page/main-page.component.ts

@ -16,10 +16,10 @@ export class MainPageComponent implements OnInit {
go2urls: {ico: string, name: string, url: string}[] = [
{ico: 'business', name: 'Серверы', url: 'servers'},
{ico: 'border_color', name: 'Правила', url: 'rules'},
{ico: 'remove_circle', name: 'Банлист', url: 'banlist'},
{ico: 'remove_circle', name: 'Баны', url: 'banlist'},
{ico: 'stars', name: 'VIP', url: 'vip'},
{ico: 'rowing', name: 'Статистика', url: 'statistic'},
{ico: 'message', name: 'Сообщения', url: 'messages'},
{ico: 'rowing', name: 'Жалобы', url: 'reports'},
{ico: 'message', name: 'Чат', url: 'messages'},
{ico: 'list_alt', name: 'Киллфид', url: 'killfeed'},
{ico: 'live_help', name: 'О нас', url: 'about'}
]

8
src/app/pages/messages-page/message-search-table.ts

@ -141,7 +141,15 @@ export class MessageSearchTable extends AbstractSearchTable<Message, MessageSear
}
override updateData() {
if (this.lazy) return;
super.updateData();
this.getMessages();
}
lazyInit() {
if (this.lazy) {
this.lazy = false;
this.updateData();
}
}
}

30
src/app/pages/profile-page/profile-page.component.html

@ -114,22 +114,22 @@
</mat-list>
</mat-expansion-panel>
<!--История банов-->
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null">
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null" (click)="appbanlistsearchtable.lazyInit()">
<mat-expansion-panel-header>
<mat-panel-title>
История банов
</mat-panel-title>
</mat-expansion-panel-header>
<app-banlist-search-table [account_id]="profile.steamids.account_id"></app-banlist-search-table>
<app-banlist-search-table #appbanlistsearchtable [lazy]="true" [account_id]="profile.steamids.account_id"></app-banlist-search-table>
</mat-expansion-panel>
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null">
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null" (click)="appdonatesearchtable.lazyInit()">
<mat-expansion-panel-header>
<mat-panel-title>
История получения VIP
</mat-panel-title>
</mat-expansion-panel-header>
<app-donate-search-table [account_id]="profile.steamids.account_id"></app-donate-search-table>
<app-donate-search-table #appdonatesearchtable [lazy]="true" [account_id]="profile.steamids.account_id"></app-donate-search-table>
</mat-expansion-panel>
<mat-expansion-panel hideToggle>
<mat-expansion-panel-header>
@ -141,35 +141,25 @@
<p>Табличку с репортом</p>
</div>
</mat-expansion-panel>
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null">
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null" (click)="appmessagesearch.lazyInit()">
<mat-expansion-panel-header>
<mat-panel-title>
Сообщения пользователя
</mat-panel-title>
</mat-expansion-panel-header>
<app-message-search [account_id]="profile.steamids.account_id"></app-message-search>
<app-message-search #appmessagesearch [lazy]="true" [account_id]="profile.steamids.account_id"></app-message-search>
</mat-expansion-panel>
<mat-expansion-panel hideToggle>
<mat-expansion-panel-header>
<mat-panel-title>
Убийства на сервере
</mat-panel-title>
</mat-expansion-panel-header>
<div>
<p>табличку с убийствами</p>
</div>
</mat-expansion-panel>
<mat-expansion-panel hideToggle>
<mat-expansion-panel hideToggle *ngIf="profile!=null && profile.steamids!=null" (click)="appkillfeedsearchtable.lazyInit()">
<mat-expansion-panel-header>
<mat-panel-title>
Смерти на сервере
Убийства/Помощь/Смерти на сервере
</mat-panel-title>
</mat-expansion-panel-header>
<div>
<p>huy</p>
<app-killfeed-search-table #appkillfeedsearchtable [lazy]="true" [account_id]="profile.steamids.account_id"></app-killfeed-search-table>
</div>
</mat-expansion-panel>
<mat-expansion-panel hideToggle>
<mat-expansion-panel hideToggle *ngIf="authService.isAdmin()">
<mat-expansion-panel-header>
<mat-panel-title>
Время загрузки данных с сервера (не для пельменя)

168
src/app/pages/reports-page/ReportSearchTable.ts

@ -0,0 +1,168 @@
import {AbstractSearchTable} from "../internal-components/abstract-search-table.component";
import {AuthService} from "../../services/auth.service";
import {ServerService} from "../../services/server.service";
import {PlayerService} from "../../services/player.service";
import {ActivatedRoute, Router} from "@angular/router";
import {HttpClient} from "@angular/common/http";
import {KillFeedSearchFilter} from "../../entities/search/KillFeedSearchFilter";
import {SearchFilter} from "../../entities/search/SearchFilter";
import {map} from "rxjs";
import {PagingAndSortingPaginator} from "../../entities/PagingAndSortingPaginator";
import {MatTableDataSource} from "@angular/material/table";
import {Component} from "@angular/core";
import {Report} from "../../entities/Report";
@Component({
selector: 'app-report-search-table',
template: `
<div style="padding-bottom: 10px;">
<mat-chip-list>
<mat-chip [matMenuTriggerFor]="addFilter">Искать по...</mat-chip>
<mat-menu #addFilter>
<button mat-menu-item [matMenuTriggerFor]="timeSelect">Времени</button>
</mat-menu>
<mat-menu #timeSelect>
<button mat-menu-item (click)="filter.addEndTimeToSearch()">До ...</button>
<button mat-menu-item (click)="filter.addBeginTimeToSearch()">После ...</button>
</mat-menu>
<mat-chip *ngIf="filter.updated" (click)="updateData()">Обновить</mat-chip>
<app-filter-mat-chip-killfeed
[filter]="filter">
</app-filter-mat-chip-killfeed>
<app-filter-mat-chip-date-begin
[filter]="filter">
</app-filter-mat-chip-date-begin>
<app-filter-mat-chip-date-end
[filter]="filter">
</app-filter-mat-chip-date-end>
</mat-chip-list>
</div>
<div>
<div class="loading-shade"
*ngIf="loading || err">
<mat-spinner *ngIf="loading"></mat-spinner>
<div class="err" *ngIf="err">
Слишком много запросов или сервер не отвечает, обнови страницу.
<br>
<button mat-button (click)="err=false; loading=false">Закрыть</button>
</div>
</div>
<table mat-table [dataSource]="dataSource" style="width: 100%">
<ng-container matColumnDef="author">
<th mat-header-cell *matHeaderCellDef> Кто пожаловался </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="row.a_nickname?aMenu:null"> {{row.a_nickname}}
<mat-menu #aMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.a_nickname)">Добавить в поиск</button>
<button mat-menu-item (click)="filter.addAccountToSearch('[U:1:'+row.a_steam.account_id+']')">Добавить в поиск используя ID</button>
<button mat-menu-item (click)="authService.searchPlayer(row.a_steam.account_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="author_kd">
<th mat-header-cell *matHeaderCellDef>К/Д</th>
<td mat-cell *matCellDef="let row"> {{row.a_kills}}/{{row.a_deads}}</td>
</ng-container>
<ng-container matColumnDef="reported">
<th mat-header-cell *matHeaderCellDef> На кого </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="row.r_nickname?rMenu:null"> {{row.r_nickname}}
<mat-menu #rMenu>
<button mat-menu-item (click)="filter.addAccountToSearch(row.r_nickname)">Добавить в поиск</button>
<button mat-menu-item (click)="filter.addAccountToSearch('[U:1:'+row.r_steam.account_id+']')">Добавить в поиск используя ID</button>
<button mat-menu-item (click)="authService.searchPlayer(row.r_steam.account_id)">Открыть профиль</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="reported_kd">
<th mat-header-cell *matHeaderCellDef>К/Д</th>
<td mat-cell *matCellDef="let row"> {{row.r_kills}}/{{row.r_deads}}</td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef> Время </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="dateMenu"> {{row.utime * 1000 | date:"HH:mm dd/MM/yyyy"}}
<mat-menu #dateMenu>
<button mat-menu-item (click)="filter.addEndTimeToSearch(row.utime * 1000)">Искать до {{row.utime * 1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
<button mat-menu-item (click)="filter.addBeginTimeToSearch(row.utime * 1000)">Искать после {{row.utime * 1000 | date:"HH:mm:ss dd/MM/yyyy"}}</button>
</mat-menu></td>
</ng-container>
<ng-container matColumnDef="reasons">
<th mat-header-cell *matHeaderCellDef>Причина</th>
<td mat-cell *matCellDef="let row"> {{row.reasons}}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Решение</th>
<td mat-cell *matCellDef="let row"> {{row.actions.length==0?'не было':row.actions}}</td>
</ng-container>
<ng-container matColumnDef="server">
<th mat-header-cell *matHeaderCellDef> Сервер </th>
<td mat-cell *matCellDef="let row" [matMenuTriggerFor]="serverMenu"> {{row.serverName}}
<mat-menu #serverMenu>
<button mat-menu-item (click)="filter.addServerToSearch(row.srv)">Добавить в поиск</button>
</mat-menu>
</td>
</ng-container>
<ng-container matColumnDef="online">
<th mat-header-cell *matHeaderCellDef>Игроков</th>
<td mat-cell *matCellDef="let row"> {{row.online}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- Row shown when there is no matching data. -->
<div *ngIf="!loading">
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">А вот и такое бывает...</td>
</tr>
</div>
</table>
<mat-paginator
[pageSizeOptions]="[5, 10, 25, 100]"
[pageSize]="10"
(page)="updateData()"
></mat-paginator>
</div>
`
})
export class ReportSearchTable extends AbstractSearchTable<ReportSearchTable, any>{
displayedColumns: string[] = [
'author', 'author_kd',
'reported', 'reported_kd',
'reasons', 'date','actions','server', 'online'];
constructor(authService: AuthService,
serverService: ServerService,
playerService: PlayerService,
router: Router,
route: ActivatedRoute,
private http: HttpClient) {
super(authService, serverService, playerService, route, router);
super.filter = new SearchFilter();//todo replace
}
private getStat() {
this.filter.updated = false;
this.loading = true;
this.http.post(`api/web/reports`, this.filter, {params:
{size: this.paginator?this.paginator.pageSize:20,
page: this.paginator?this.paginator.pageIndex:0}
}).pipe(map((res) => PagingAndSortingPaginator<Report>.newObj().fromData(res).updatePaginator(this.paginator)))
.subscribe((res) => {
this.dataSource = new MatTableDataSource<ReportSearchTable>(res.data);
this.err = false;
}, (e) => this.err = true, () => this.loading = false
);
}
override updateData() {
if (this.lazy) return;
super.updateData();
this.getStat();
}
lazyInit() {
if (this.lazy) {
this.lazy = false;
this.updateData();
}
}
}

0
src/app/pages/reports-page/reports-page.component.scss

28
src/app/pages/reports-page/reports-page.component.ts

@ -0,0 +1,28 @@
import { Component, OnInit } from '@angular/core';
import {AuthService} from "../../services/auth.service";
@Component({
selector: 'app-reports-page',
styleUrls: ['./reports-page.component.scss'],
template: `
<div class="content-in-center-header" style="flex-direction: column;">
<h1>Жалобы на игроков</h1>
<h3>Ты можешь отправить жалобу из игры через команду !report</h3>
</div>
<div class="content-in-center">
<div class="content-in-border">
<app-need-auth-to-continue *ngIf="!authService.isAuth()"></app-need-auth-to-continue>
<app-report-search-table *ngIf="authService.isAuth()"></app-report-search-table>
</div>
</div>
`
})
export class ReportsPageComponent implements OnInit {
constructor(public authService: AuthService) { }
ngOnInit(): void {
}
}

56
src/app/pages/statistic-page/statistic-page.component.html

@ -1,9 +1,26 @@
<div class="content-in-center-header" style="flex-direction: column;">
<h1>Статистика</h1>
<h3>Разнообразная статистика с наших серверов</h3>
</div>
<div class="content-in-center">
<div class="content-in-border" *ngIf="uniq">
<h2>Уникальные игроки</h2>
<h4>За "уникальность" берется игрок который зашел за данный период первый раз и поиграл более 5 минут</h4>
<div class="container responsive-grid-250">
<mat-card>
<mat-card-title>{{uniq.day}}</mat-card-title>
<mat-card-subtitle>игроков за день</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.month}}</mat-card-title>
<mat-card-subtitle>игроков за месяц</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.year}}</mat-card-title>
<mat-card-subtitle>игроков за год</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.total}}</mat-card-title>
<mat-card-subtitle>игроков за всё время</mat-card-subtitle>
</mat-card>
</div>
</div>
<div class="content-in-border">
<h2>График онлайна</h2>
<div *ngIf="!init">
@ -49,33 +66,4 @@
</div>
<button mat-button mat-raised-button *ngIf="init" (click)="getGraph()">Загрузить график</button>
</div>
<div class="content-in-border">
<h2>Уникальные игроки</h2>
<h4>За "уникальность" берется игрок который зашел за данный период первый раз и поиграл более 5 минут</h4>
<div class="container responsive-grid-250">
<mat-card>
<mat-card-title>{{uniq.day}}</mat-card-title>
<mat-card-subtitle>игроков за день</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.month}}</mat-card-title>
<mat-card-subtitle>игроков за месяц</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.year}}</mat-card-title>
<mat-card-subtitle>игроков за год</mat-card-subtitle>
</mat-card>
<mat-card>
<mat-card-title>{{uniq.total}}</mat-card-title>
<mat-card-subtitle>игроков за всё время</mat-card-subtitle>
</mat-card>
</div>
</div>
<div class="content-in-border">
<h2>Последние выданые випки</h2>
<div>
<app-need-auth-to-continue *ngIf="!authService.isAuth()"></app-need-auth-to-continue>
<app-donate-search-table *ngIf="authService.isAuth()"></app-donate-search-table>
</div>
</div>
</div>

5
src/app/pages/statistic-page/statistic-page.component.ts

@ -46,7 +46,8 @@ export class StatisticPageComponent implements OnInit {
constructor(private graphService: GraphService,
private actionService: ActionService,
private serverService: ServerService,
public authService: AuthService) { }
public authService: AuthService) {
}
ngOnInit(): void {
this.getServers();
@ -62,10 +63,12 @@ export class StatisticPageComponent implements OnInit {
getServers() {
this.serverService.servers.subscribe(
(res) => {
console.log(res);
const keys = Object.keys(res.data);
for (const key of keys) {
this.serverList.push({name: res.data[key].name, server_id: key});
}
console.log(this.serverList)
}
)
}

8
src/app/pages/vip-page/vip-page.component.html

@ -62,5 +62,13 @@
</mat-accordion>
</div>
</div>
<div class="content-in-border">
<h2 style="color: black">Последние выданые випки</h2>
<div>
<app-need-auth-to-continue *ngIf="!authService.isAuth()"></app-need-auth-to-continue>
<app-donate-search-table *ngIf="authService.isAuth()"></app-donate-search-table>
</div>
</div>
</div>

4
src/app/pages/vip-page/vip-page.component.ts

@ -5,6 +5,7 @@ import {MatDialog, MatDialogConfig, MatDialogRef} from "@angular/material/dialog
import {VipBuyDialog} from "./VipBuyDialog";
import {VipFreeDialog} from "./VipFreeDialog";
import {VipPromocodeDialog} from "./VipPromocodeDialog";
import {AuthService} from "../../services/auth.service";
@Component({
selector: 'app-vip-page',
@ -35,7 +36,8 @@ export class VipPageComponent implements OnInit {
];
constructor(private vipService: VipService,
private dialog: MatDialog) { }
private dialog: MatDialog,
public authService: AuthService) { }
ngOnInit(): void {
this.getVips();

15
src/app/services/server.service.ts

@ -7,18 +7,23 @@ import {StatExporter} from "../entities/servers/StatExporter";
providedIn: 'root'
})
export class ServerService {
public servers: Observable<StatExporter<any>> = of();
constructor(private http: HttpClient) {
this.http.get(`api/stats?filter=servers`).pipe(
this.getServers().subscribe((res) => {
this.servers = of(res);
console.log(res);
})
}
getServers():Observable<StatExporter<any>> {
return this.http.get(`api/stats?filter=servers`).pipe(
map((res) => {
const d = new StatExporter();
d.fromData(res, 'servers');
return d;
})).subscribe((res) => {
this.servers = of(res);
})
}))
}
servers: Observable<StatExporter<any>> = of();
getStats(filter: string): Observable<StatExporter<any>> {
return this.http.get(`api/stats?filter=${filter}`).pipe(

Loading…
Cancel
Save