Files
wenzi/src/main/java/com/mosquito/project/controller/DashboardController.java

351 lines
14 KiB
Java
Raw Normal View History

package com.mosquito.project.controller;
import com.mosquito.project.domain.Activity;
import com.mosquito.project.dto.ActivityStatsResponse;
import com.mosquito.project.dto.ApiResponse;
import com.mosquito.project.service.ActivityService;
import com.mosquito.project.permission.ApprovalFlowService;
import com.mosquito.project.permission.SysApprovalRecord;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 仪表盘控制器 - 提供管理后台首页数据
*/
@RestController
@RequestMapping("/api/dashboard")
public class DashboardController {
private final ActivityService activityService;
private final ApprovalFlowService approvalFlowService;
public DashboardController(
ActivityService activityService,
ApprovalFlowService approvalFlowService) {
this.activityService = activityService;
this.approvalFlowService = approvalFlowService;
}
/**
* 获取仪表盘数据
*/
@GetMapping
public ResponseEntity<ApiResponse<Map<String, Object>>> getDashboard() {
Map<String, Object> data = new HashMap<>();
// KPI数据
data.put("kpis", buildKpiData());
// 活动列表
data.put("activities", buildActivityList());
// 告警/异常
data.put("alerts", buildAlerts());
// 待办事项
data.put("todos", buildTodos());
// 更新时间
data.put("updatedAt", LocalDateTime.now().toString());
return ResponseEntity.ok(ApiResponse.success(data));
}
/**
* 获取KPI统计数据
*/
@GetMapping("/kpis")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getKpis() {
return ResponseEntity.ok(ApiResponse.success(buildKpiData()));
}
/**
* 获取活动统计摘要
*/
@GetMapping("/activities")
public ResponseEntity<ApiResponse<Map<String, Object>>> getActivitiesSummary() {
Map<String, Object> summary = new HashMap<>();
List<Activity> activities = activityService.getAllActivities();
// 统计活动数量
summary.put("total", activities.size());
// 活动列表(简要信息)
List<Map<String, Object>> activityList = activities.stream()
.limit(10)
.map(this::convertActivitySummary)
.collect(Collectors.toList());
summary.put("list", activityList);
return ResponseEntity.ok(ApiResponse.success(summary));
}
/**
* 获取待办事项
*/
@GetMapping("/todos")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getTodoList() {
return ResponseEntity.ok(ApiResponse.success(buildTodos()));
}
private List<Map<String, Object>> buildKpiData() {
List<Map<String, Object>> kpis = new ArrayList<>();
// 获取统计数据
List<Activity> activities = activityService.getAllActivities();
long totalActivities = activities.size();
// 待审批数量
long pendingApprovals = approvalFlowService.getPendingApprovals(1L).size();
// 后续可接入实际统计服务的数据
long totalUsers = 0L;
long pendingRewards = 0L;
long pendingRisks = 0L;
// 访问量(模拟数据)
Map<String, Object> visits = new HashMap<>();
visits.put("label", "访问");
visits.put("value", 0L);
visits.put("status", totalActivities > 0 ? "正常" : "待同步");
visits.put("hint", "接入埋点后显示实时数据");
kpis.add(visits);
// 分享数(模拟数据)
Map<String, Object> shares = new HashMap<>();
shares.put("label", "分享");
shares.put("value", 0L);
shares.put("status", totalActivities > 0 ? "正常" : "待同步");
shares.put("hint", "活动开启后统计分享次数");
kpis.add(shares);
// 转化数(模拟数据)
Map<String, Object> conversions = new HashMap<>();
conversions.put("label", "转化");
conversions.put("value", 0L);
conversions.put("status", totalUsers > 0 ? "正常" : "待同步");
conversions.put("hint", "用户注册转化将在此展示");
kpis.add(conversions);
// 新增用户
Map<String, Object> newUsers = new HashMap<>();
newUsers.put("label", "新增");
newUsers.put("value", totalUsers);
newUsers.put("status", "正常");
newUsers.put("hint", "当前用户总数");
kpis.add(newUsers);
// 奖励待审批
Map<String, Object> pendingRewardKpi = new HashMap<>();
pendingRewardKpi.put("label", "待审批奖励");
pendingRewardKpi.put("value", pendingRewards);
pendingRewardKpi.put("status", pendingRewards > 0 ? "待处理" : "已清零");
pendingRewardKpi.put("hint", "待审批的奖励申请");
kpis.add(pendingRewardKpi);
// 待审批
Map<String, Object> pendingApprovalKpi = new HashMap<>();
pendingApprovalKpi.put("label", "待审批");
pendingApprovalKpi.put("value", pendingApprovals);
pendingApprovalKpi.put("status", pendingApprovals > 0 ? "待处理" : "已清零");
pendingApprovalKpi.put("hint", "待审批的申请");
kpis.add(pendingApprovalKpi);
// 风险告警
Map<String, Object> riskKpi = new HashMap<>();
riskKpi.put("label", "风险告警");
riskKpi.put("value", pendingRisks);
riskKpi.put("status", pendingRisks > 0 ? "需关注" : "正常");
riskKpi.put("hint", "待处理的风险告警");
kpis.add(riskKpi);
return kpis;
}
private List<Map<String, Object>> buildActivityList() {
List<Activity> activities = activityService.getAllActivities();
return activities.stream()
.limit(10)
.map(this::convertActivitySummary)
.collect(Collectors.toList());
}
private Map<String, Object> convertActivitySummary(Activity activity) {
Map<String, Object> summary = new HashMap<>();
summary.put("id", activity.getId());
summary.put("name", activity.getName());
summary.put("startTime", activity.getStartTime() != null ? activity.getStartTime().toString() : null);
summary.put("endTime", activity.getEndTime() != null ? activity.getEndTime().toString() : null);
// 获取活动统计
try {
ActivityStatsResponse stats = activityService.getActivityStats(activity.getId());
summary.put("participants", stats.getTotalParticipants());
summary.put("shares", stats.getTotalShares());
summary.put("conversions", stats.getTotalParticipants());
} catch (Exception e) {
summary.put("participants", 0);
summary.put("shares", 0);
summary.put("conversions", 0);
}
return summary;
}
private List<Map<String, Object>> buildAlerts() {
List<Map<String, Object>> alerts = new ArrayList<>();
// 检查待审批记录
List<SysApprovalRecord> pendingRecords = approvalFlowService.getPendingApprovals(1L);
if (!pendingRecords.isEmpty()) {
Map<String, Object> alert = new HashMap<>();
alert.put("title", "待审批事项");
alert.put("detail", pendingRecords.size() + "条申请待审批");
alert.put("type", "APPROVAL");
alert.put("level", "INFO");
alerts.add(alert);
}
return alerts;
}
private List<Map<String, Object>> buildTodos() {
List<Map<String, Object>> todos = new ArrayList<>();
// 待审批记录
List<SysApprovalRecord> pendingRecords = approvalFlowService.getPendingApprovals(1L);
if (!pendingRecords.isEmpty()) {
Map<String, Object> todo = new HashMap<>();
todo.put("id", "approval-pending");
todo.put("title", "审批申请");
todo.put("description", pendingRecords.size() + "条申请待审批");
todo.put("type", "APPROVAL");
todo.put("link", "/approvals");
todo.put("priority", "HIGH");
todos.add(todo);
}
return todos;
}
/**
* 导出仪表盘数据为CSV
*/
@GetMapping("/export")
public ResponseEntity<byte[]> exportDashboard(@RequestParam(defaultValue = "csv") String format) {
StringBuilder csv = new StringBuilder();
csv.append("导出时间:").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("\n\n");
// KPI数据
csv.append("KPI指标\n");
csv.append("指标,数值,状态,说明\n");
for (Map<String, Object> kpi : buildKpiData()) {
csv.append(kpi.get("label")).append(",")
.append(kpi.get("value")).append(",")
.append(kpi.get("status")).append(",")
.append(kpi.get("hint")).append("\n");
}
csv.append("\n");
// 活动数据
csv.append("活动列表\n");
csv.append("ID,名称,开始时间,结束时间,参与人数,分享数,转化数\n");
for (Activity activity : activityService.getAllActivities()) {
csv.append(activity.getId()).append(",")
.append(escapeCsv(activity.getName())).append(",")
.append(activity.getStartTime() != null ? activity.getStartTime().toString() : "").append(",")
.append(activity.getEndTime() != null ? activity.getEndTime().toString() : "").append(",");
try {
ActivityStatsResponse stats = activityService.getActivityStats(activity.getId());
csv.append(stats.getTotalParticipants()).append(",")
.append(stats.getTotalShares()).append(",")
.append(stats.getTotalParticipants()).append("\n");
} catch (Exception e) {
csv.append("0,0,0\n");
}
}
byte[] body = csv.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"dashboard_export_" +
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".csv\"");
return new ResponseEntity<>(body, headers, org.springframework.http.HttpStatus.OK);
}
/**
* 导出KPI数据为CSV
*/
@GetMapping("/kpis/export")
public ResponseEntity<byte[]> exportKpis() {
StringBuilder csv = new StringBuilder();
csv.append("指标,数值,状态,说明\n");
for (Map<String, Object> kpi : buildKpiData()) {
csv.append(kpi.get("label")).append(",")
.append(kpi.get("value")).append(",")
.append(kpi.get("status")).append(",")
.append(kpi.get("hint")).append("\n");
}
byte[] body = csv.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"kpi_export_" +
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".csv\"");
return new ResponseEntity<>(body, headers, org.springframework.http.HttpStatus.OK);
}
/**
* 导出活动数据为CSV
*/
@GetMapping("/activities/export")
public ResponseEntity<byte[]> exportActivities() {
StringBuilder csv = new StringBuilder();
csv.append("ID,名称,开始时间,结束时间,参与人数,分享数,转化数\n");
for (Activity activity : activityService.getAllActivities()) {
csv.append(activity.getId()).append(",")
.append(escapeCsv(activity.getName())).append(",")
.append(activity.getStartTime() != null ? activity.getStartTime().toString() : "").append(",")
.append(activity.getEndTime() != null ? activity.getEndTime().toString() : "").append(",");
try {
ActivityStatsResponse stats = activityService.getActivityStats(activity.getId());
csv.append(stats.getTotalParticipants()).append(",")
.append(stats.getTotalShares()).append(",")
.append(stats.getTotalParticipants()).append("\n");
} catch (Exception e) {
csv.append("0,0,0\n");
}
}
byte[] body = csv.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("text/csv; charset=UTF-8"));
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"activity_export_" +
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".csv\"");
return new ResponseEntity<>(body, headers, org.springframework.http.HttpStatus.OK);
}
/**
* 转义CSV特殊字符
*/
private String escapeCsv(String value) {
if (value == null) return "";
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
return "\"" + value.replace("\"", "\"\"") + "\"";
}
return value;
}
}