Browse Source

extra graph

master
gsd 1 month ago
parent
commit
b5fc043aaf
  1. 22
      src/main/java/app/controllers/user/PublicController.java
  2. 50
      src/main/java/app/controllers/user/UsertimeController.java
  3. 26
      src/main/java/app/entities/SearchFilter.java
  4. 33
      src/main/java/app/entities/db/period/PerPeriodStatistic.java
  5. 76
      src/main/java/app/services/db/GraphService.java

22
src/main/java/app/controllers/user/PublicController.java

@ -5,9 +5,11 @@ import app.annotations.enums.FirstTouch;
import app.annotations.interfaces.CheckWebAccess;
import app.annotations.interfaces.CollectStatistic;
import app.annotations.interfaces.WaitAfterNext;
import app.entities.SearchFilter;
import app.entities.db.Annonce;
import app.entities.db.ban.Ban;
import app.entities.db.ban.BanSearchFilter;
import app.entities.db.period.PerPeriodStatistic;
import app.entities.report.Report;
import app.entities.report.ReportSearchFilter;
import app.repositories.AnnonceRepository;
@ -15,6 +17,7 @@ import app.repositories.BanRepository;
import app.repositories.ReportRepository;
import app.services.ProfileService;
import app.services.db.BanService;
import app.services.db.GraphService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
@ -24,6 +27,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
@ -48,6 +53,9 @@ public class PublicController {
@Autowired
private ReportRepository reportRepository;
@Autowired
private GraphService graphService;
@Autowired
public PublicController(BanService banService) {
this.banService = banService;
@ -122,4 +130,18 @@ public class PublicController {
public ResponseEntity<Page<Annonce>> getAnnonces(Pageable pageable) {
return ResponseEntity.ok(annonceRepository.getAnnonce(pageable));
}
@PostMapping("/vip/graph")
@WaitAfterNext(order = "vipgraph")
public ResponseEntity<List<GraphService.VipPerPeriodStatistic>> getTimeOnPeriod(@RequestBody(required = false) SearchFilter searchFilter) {
if (searchFilter == null) searchFilter = new SearchFilter();
if (searchFilter.getEndTime() == null)
searchFilter.setEnd(Timestamp.from(Instant.now()).toLocalDateTime());
if (searchFilter.getBeginTime() == null)
searchFilter.setBegin(Timestamp.from(Instant.now().minusSeconds(30 * 3600* 24)).toLocalDateTime());
return new ResponseEntity<>(graphService.getVipOnPeriod(
searchFilter
), HttpStatus.OK);
}
}

50
src/main/java/app/controllers/user/UsertimeController.java

@ -0,0 +1,50 @@
package app.controllers.user;
import app.annotations.enums.AuthMethod;
import app.annotations.interfaces.CheckWebAccess;
import app.annotations.interfaces.CollectStatistic;
import app.annotations.interfaces.WaitAfterNext;
import app.entities.SearchFilter;
import app.entities.db.period.PerPeriodStatistic;
import app.services.db.GraphService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;
/**
* POST http://localhost:8080/api/profile/usertime
* Content-Type: application/json
*
* {
* "accounts": ["76561198087598690"],
* "end": "2026-05-10T23:59:59.999Z",
* "begin": "2026-04-10T23:59:59.999Z"
* }
*/
@RestController
@RequestMapping("/api/profile/usertime")
public class UsertimeController {
@Autowired
private GraphService graphService;
@PostMapping("/graph")
@CheckWebAccess(auth_method = AuthMethod.STEAM64)
@WaitAfterNext(order = "usertime")
@CollectStatistic
public ResponseEntity<List<PerPeriodStatistic>> getTimeOnPeriod(@RequestBody(required = false) SearchFilter searchFilter) {
if (searchFilter == null) searchFilter = new SearchFilter();
if (searchFilter.getEndTime() == null)
searchFilter.setEnd(Timestamp.from(Instant.now()).toLocalDateTime());
if (searchFilter.getBeginTime() == null)
searchFilter.setBegin(Timestamp.from(Instant.now().minusSeconds(30 * 3600* 24)).toLocalDateTime());
return new ResponseEntity<>(graphService.getUsertimeOnPeriod(
searchFilter
), HttpStatus.OK);
}
}

26
src/main/java/app/entities/SearchFilter.java

@ -7,6 +7,7 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -21,6 +22,10 @@ public class SearchFilter {
private String serverId = null;
private Long utc = 0L;
public boolean isEmpty() {
return accounts == null || accounts.isEmpty() || begin == null || end == null;
}
/**
* Выдает список из ид 3 версии [U:1:127332962]
* @param profileService
@ -88,7 +93,28 @@ public class SearchFilter {
return end == null ? null : (Timestamp.valueOf(end).getTime()/1000) + utc*60;
}
public Timestamp getBeginTime() {
return begin == null ? null : Timestamp.valueOf(begin);
}
public Timestamp getEndTime() {
return end == null ? null : Timestamp.valueOf(end);
}
public String getServerId() {
return serverId == null || serverId.isEmpty() ? null : serverId;
}
public Long getDayDelta() {
if (begin != null && end != null)
return ChronoUnit.DAYS.between(begin, end);
else return 0L;
}
public String getMaybePeriod() {
long delta = getDayDelta();
if (delta <= 30) return "day";
if (delta <= 365) return "month";
else return "year";
}
}

33
src/main/java/app/entities/db/period/PerPeriodStatistic.java

@ -0,0 +1,33 @@
package app.entities.db.period;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
@Data
public class PerPeriodStatistic {
private final static SimpleDateFormat simpleDaysDateFormat = new SimpleDateFormat("dd.MM.yyyy");
private final static SimpleDateFormat simpleMonthDateFormat = new SimpleDateFormat("MM.yyyy");
private final static SimpleDateFormat simpleYearDateFormat = new SimpleDateFormat("yyyy");
private Timestamp ts;
private Long value;
private String srv_id;
private String period;
@JsonIgnore
public Timestamp getTs() {
return ts;
}
public String getDate() {
if (ts == null) return "";
return switch (period) {
case "day" -> simpleDaysDateFormat.format(ts);
case "month" -> simpleMonthDateFormat.format(ts);
case "year" -> simpleYearDateFormat.format(ts);
default -> "";
};
}
}

76
src/main/java/app/services/db/GraphService.java

@ -0,0 +1,76 @@
package app.services.db;
import app.entities.SearchFilter;
import app.entities.db.period.PerPeriodStatistic;
import app.services.ProfileService;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GraphService {
@Autowired
private ProfileService profileService;
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
/**
* 2021-03-08 00:00:00.000000 +00:00,3853,srv1
* 2021-03-12 00:00:00.000000 +00:00,930,srv1
* 2021-04-13 00:00:00.000000 +00:00,435,srv1
* 2021-05-01 00:00:00.000000 +00:00,2706,srv1
* 2021-05-02 00:00:00.000000 +00:00,2628,srv10
* @param searchFilter
* @return
*/
public List<PerPeriodStatistic> getUsertimeOnPeriod(SearchFilter searchFilter) {
final String sql = "select date_trunc(:delta, timestamp) AS ts, :delta as period, sum(connect_duration) as value, srv_id from user_connections " +
"where (:account_ids_empty = true or account_id in (:account_ids)) and connect_duration != 0 and timestamp between :begindate and :enddate " +
"and (:srv_id like '' or srv_id like :srv_id) " +
"group by ts, srv_id";
MapSqlParameterSource map = new MapSqlParameterSource();
map.addValue("delta", searchFilter.getMaybePeriod());
List<Long> profiles = searchFilter.getAccounts(profileService);
map.addValue("account_ids_empty", profiles.isEmpty());
map.addValue("account_ids", profiles.isEmpty() ? List.of(1) : profiles);
map.addValue("begindate", searchFilter.getBeginTime());
map.addValue("enddate", searchFilter.getEndTime());
map.addValue("srv_id", searchFilter.getServerId() == null ? "" : searchFilter.getServerId());
return namedParameterJdbcTemplate.query(sql, map, new BeanPropertyRowMapper(PerPeriodStatistic.class));
}
@Data
public static class VipPerPeriodStatistic extends PerPeriodStatistic {
private Integer givemethod;
private Integer amount;
@JsonIgnore
@Override
public String getSrv_id() {
return super.getSrv_id();
}
}
public List<VipPerPeriodStatistic> getVipOnPeriod(SearchFilter searchFilter) {
final String sql = "select date_trunc(:delta, timestamp) AS ts, :delta as period, count(*) as value, givemethod, amount from gived_vip " +
"where (:account_ids_empty = true or steam2 in (:account_ids)) and givemethod != 4 and timestamp between :begindate and :enddate " +
"group by ts, givemethod, amount";
MapSqlParameterSource map = new MapSqlParameterSource();
map.addValue("delta", searchFilter.getMaybePeriod());
String profiles = searchFilter.getAccountsSteam2(profileService);
map.addValue("account_ids_empty", profiles.isEmpty());
map.addValue("account_ids", profiles.isEmpty() ? "0" : profiles);
map.addValue("begindate", searchFilter.getBeginTime());
map.addValue("enddate", searchFilter.getEndTime());
return namedParameterJdbcTemplate.query(sql, map, new BeanPropertyRowMapper(VipPerPeriodStatistic.class));
}
}
Loading…
Cancel
Save