| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package com.pharmacopoeia.controller;
- import com.pharmacopoeia.dto.ApiResponse;
- import com.pharmacopoeia.service.AnalyticsService;
- import com.pharmacopoeia.util.IpUtils;
- import jakarta.servlet.http.HttpServletRequest;
- import org.springframework.http.ResponseEntity;
- import org.springframework.web.bind.annotation.*;
- import java.util.Map;
- @RestController
- @RequestMapping("/api/v1/analytics")
- public class AnalyticsController {
- private final AnalyticsService analyticsService;
- private final HttpServletRequest request;
- public AnalyticsController(AnalyticsService analyticsService, HttpServletRequest request) {
- this.analyticsService = analyticsService;
- this.request = request;
- }
- // ==================== 事件 ====================
- @GetMapping("/events")
- public ResponseEntity<ApiResponse<Map<String, Object>>> queryEvents(
- @RequestParam(required = false) String eventType,
- @RequestParam(required = false) String startDate,
- @RequestParam(required = false) String endDate,
- @RequestParam(defaultValue = "1") int page,
- @RequestParam(defaultValue = "20") int pageSize) {
- return ResponseEntity.ok(ApiResponse.success(
- analyticsService.queryEvents(eventType, startDate, endDate, page, pageSize)));
- }
- @GetMapping("/events/{id}")
- public ResponseEntity<ApiResponse<Map<String, Object>>> getEventDetail(@PathVariable long id) {
- var detail = analyticsService.getEventDetail(id);
- if (detail.isEmpty()) {
- return ResponseEntity.ok(ApiResponse.<Map<String, Object>>builder().code(404).message("事件不存在").build());
- }
- return ResponseEntity.ok(ApiResponse.success(detail));
- }
- @PostMapping("/events")
- public ResponseEntity<ApiResponse<Map<String, String>>> saveEvent(@RequestBody Map<String, Object> body) {
- String eventType = (String) body.getOrDefault("event_type", "unknown");
- @SuppressWarnings("unchecked")
- Map<String, Object> eventData = body.get("event_data") instanceof Map
- ? (Map<String, Object>) body.get("event_data") : Map.of();
- String pageUrl = (String) body.getOrDefault("page_url", "");
- String referrer = (String) body.getOrDefault("referrer", "");
- String userKey = getCurrentUserKey();
- String ip = IpUtils.getClientIp(request);
- String ua = request.getHeader("User-Agent");
- analyticsService.saveEvent(userKey, eventType, eventData, pageUrl, referrer,
- ip, ua != null ? ua : "");
- return ResponseEntity.accepted()
- .body(ApiResponse.<Map<String, String>>builder().code(202).message("accepted")
- .data(Map.of("status", "accepted")).build());
- }
- // ==================== 概览 ====================
- /** 概览数字:total_events / active_users / page_views / searches / ai_qa */
- @GetMapping("/stats/overview")
- public ResponseEntity<ApiResponse<Map<String, Object>>> queryOverview(
- @RequestParam(required = false) String range) {
- if (range == null || range.isBlank()) {
- range = "total";
- }
- return ResponseEntity.ok(ApiResponse.success(analyticsService.queryOverview(range)));
- }
- // ==================== 维度 ====================
- /** 分页维度统计:dimension=ip/url/type/user/user_ip */
- @GetMapping("/stats/dimension")
- public ResponseEntity<ApiResponse<Map<String, Object>>> queryDimension(
- @RequestParam String dimension,
- @RequestParam(required = false) String startDate,
- @RequestParam(required = false) String endDate,
- @RequestParam(defaultValue = "1") int page,
- @RequestParam(defaultValue = "20") int pageSize) {
- return ResponseEntity.ok(ApiResponse.success(
- analyticsService.queryDimension(dimension, startDate, endDate, page, pageSize)));
- }
- private String getCurrentUserKey() {
- var auth = org.springframework.security.core.context.SecurityContextHolder
- .getContext().getAuthentication();
- if (auth != null && auth.isAuthenticated()
- && !"anonymousUser".equals(auth.getPrincipal())) {
- return auth.getName();
- }
- return "anonymous";
- }
- }
|