新增分析:实现管理驾驶舱聚合接口与可视化

This commit is contained in:
wangzhibiao committed 2026-09-20 20:36:30 +08:00
1 parent 992791b7bd
commit f17526b409
23 files changed
+3077 -23

No files matched your search

@@ -0,0 +1,83 @@
package com.ruoyi.web.controller.train;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.train.domain.analysis.AttendanceChartsVo;
import com.ruoyi.train.domain.analysis.AttendanceFilterDto;
import com.ruoyi.train.domain.analysis.AttendanceSummaryVo;
import com.ruoyi.train.domain.analysis.DashboardChartsVo;
import com.ruoyi.train.domain.analysis.DashboardOverviewVo;
import com.ruoyi.train.domain.analysis.Student360Vo;
import com.ruoyi.train.service.ITrainAnalysisService;
/**
* 数据分析与可视化 Controller
*/
@RestController
@RequestMapping("/train/analysis")
public class TrainAnalysisController extends BaseController
{
@Autowired
private ITrainAnalysisService analysisService;
/**
* 获取管理驾驶舱宏观概览与业务提醒
*/
@PreAuthorize("@ss.hasPermi('train:analysis:dashboard')")
@GetMapping("/dashboard/overview")
public AjaxResult getDashboardOverview()
{
DashboardOverviewVo vo = analysisService.getDashboardOverview();
return success(vo);
}
/**
* 获取管理驾驶舱图表数据
*/
@PreAuthorize("@ss.hasPermi('train:analysis:dashboard')")
@GetMapping("/dashboard/charts")
public AjaxResult getDashboardCharts()
{
DashboardChartsVo vo = analysisService.getDashboardCharts();
return success(vo);
}
/**
* 获取考勤专题分析汇总 KPI
*/
@PreAuthorize("@ss.hasPermi('train:analysis:attendance')")
@GetMapping("/attendance/summary")
public AjaxResult getAttendanceSummary(AttendanceFilterDto filter)
{
AttendanceSummaryVo vo = analysisService.getAttendanceSummary(filter);
return success(vo);
}
/**
* 获取考勤专题分析图表集合
*/
@PreAuthorize("@ss.hasPermi('train:analysis:attendance')")
@GetMapping("/attendance/charts")
public AjaxResult getAttendanceCharts(AttendanceFilterDto filter)
{
AttendanceChartsVo vo = analysisService.getAttendanceCharts(filter);
return success(vo);
}
/**
* 获取指定学员 360 客观全景画像 (复用现有 train:portrait:query 权限)
*/
@PreAuthorize("@ss.hasPermi('train:portrait:query')")
@GetMapping("/portrait/student-360/{studentId}")
public AjaxResult getStudent360(@PathVariable("studentId") String studentId)
{
Student360Vo vo = analysisService.getStudent360(studentId);
return success(vo);
}
}
@@ -0,0 +1,55 @@
package com.ruoyi.web.controller.train;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import org.junit.Test;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.train.domain.analysis.AttendanceFilterDto;
/**
* 数据分析与可视化 Controller 契约与权限边界测试
*/
public class TrainAnalysisControllerContractTest
{
@Test
public void shouldExposeAllFiveAnalyticsEndpointsAndCorrectPermissions() throws Exception
{
// 1. Controller 根路径
RequestMapping root = TrainAnalysisController.class.getAnnotation(RequestMapping.class);
assertNotNull(root);
assertEquals("/train/analysis", root.value()[0]);
// 2. 驾驶舱概览
Method overview = TrainAnalysisController.class.getMethod("getDashboardOverview");
assertNotNull(overview.getAnnotation(GetMapping.class));
assertEquals("/dashboard/overview", overview.getAnnotation(GetMapping.class).value()[0]);
assertEquals("@ss.hasPermi('train:analysis:dashboard')", overview.getAnnotation(PreAuthorize.class).value());
// 3. 驾驶舱图表
Method dashCharts = TrainAnalysisController.class.getMethod("getDashboardCharts");
assertNotNull(dashCharts.getAnnotation(GetMapping.class));
assertEquals("/dashboard/charts", dashCharts.getAnnotation(GetMapping.class).value()[0]);
assertEquals("@ss.hasPermi('train:analysis:dashboard')", dashCharts.getAnnotation(PreAuthorize.class).value());
// 4. 考勤汇总 KPI
Method attSummary = TrainAnalysisController.class.getMethod("getAttendanceSummary", AttendanceFilterDto.class);
assertNotNull(attSummary.getAnnotation(GetMapping.class));
assertEquals("/attendance/summary", attSummary.getAnnotation(GetMapping.class).value()[0]);
assertEquals("@ss.hasPermi('train:analysis:attendance')", attSummary.getAnnotation(PreAuthorize.class).value());
// 5. 考勤图表集合
Method attCharts = TrainAnalysisController.class.getMethod("getAttendanceCharts", AttendanceFilterDto.class);
assertNotNull(attCharts.getAnnotation(GetMapping.class));
assertEquals("/attendance/charts", attCharts.getAnnotation(GetMapping.class).value()[0]);
assertEquals("@ss.hasPermi('train:analysis:attendance')", attCharts.getAnnotation(PreAuthorize.class).value());
// 6. 学员 360 画像 (复用现有 train:portrait:query)
Method s360 = TrainAnalysisController.class.getMethod("getStudent360", String.class);
assertNotNull(s360.getAnnotation(GetMapping.class));
assertEquals("/portrait/student-360/{studentId}", s360.getAnnotation(GetMapping.class).value()[0]);
assertEquals("@ss.hasPermi('train:portrait:query')", s360.getAnnotation(PreAuthorize.class).value());
}
}