package com.zc.business.controller; import com.alibaba.fastjson.JSONArray; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.StakeMarkUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.zc.business.domain.*; import com.zc.business.domain.export.ManyTimesInterval; import com.zc.business.domain.export.RealTimeTrafficFlow; import com.zc.business.domain.export.SectionTrafficRanking; import com.zc.business.domain.export.TrafficPeriodAnalysis; import com.zc.business.request.DcTrafficMetricsDataRequest; import com.zc.business.request.DcTrafficSectionDataRequest; import com.zc.business.service.*; import com.zc.common.core.httpclient.exception.HttpException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * 交通数据统计 * * @author xiepufeng */ @Api(tags = "交通数据统计") @RestController @RequestMapping("/business/traffic-statistics") public class DcTrafficStatisticsController extends BaseController { @Autowired private IDcTrafficSectionStatisticsService dcTrafficSectionStatisticsService; @Autowired private IDcTrafficStatisticsService dcTrafficStatisticsService; @Autowired private IDcTollStationStatisticsDataService dcTollStationStatisticsDataService; @Autowired private IDcGantryStatisticsDataService dcGantryStatisticsDataService; @Autowired private IDcGantryMetricsStatisticsDataService dcGantryMetricsStatisticsDataService; /** * 获取当前交通截面数据 * * @param request 请求参数,封装了对于交通截面数据查询的详细要求 * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前交通截面的数据(DcTrafficSectionData类型) */ @ApiOperation("获取当前交通截面数据") @GetMapping("/current/sections") public AjaxResult currentSections(DcTrafficSectionDataRequest request){ // 调用服务层方法,查询当前交通截面数据 List dcTrafficMetricsData = dcTrafficSectionStatisticsService.currentSections(request); // 将查询结果封装为AjaxResult对象返回 return AjaxResult.success(dcTrafficMetricsData); } /** * 获取历史交通截面数据 * * @param request 包含交通截面数据请求参数的对象 * @return 返回一个包含历史交通截面数据的AjaxResult对象 */ @ApiOperation("获取历史交通截面数据") @GetMapping("/history/sections") public AjaxResult historySections(DcTrafficSectionDataRequest request){ // 调用服务层方法,获取历史交通截面的统计数据 List dcTrafficMetricsData = dcTrafficSectionStatisticsService.historySections(request); // 将获取到的历史交通截面数据封装成AjaxResult对象并返回 return AjaxResult.success(dcTrafficMetricsData); } /** * 获取当前交通特征指数 * * @param request 请求参数,封装了获取交通指标所需的数据和条件 * @return 返回当前交通特征指数的数据结果,使用AjaxResult包装 */ @ApiOperation("获取当前交通特征指数") @GetMapping("/current/metrics") public AjaxResult currentTrafficMetrics(DcTrafficMetricsDataRequest request){ // 调用服务层方法,获取当前交通指标数据 List dcTrafficMetricsData = dcTrafficSectionStatisticsService.currentTrafficMetrics(request); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(dcTrafficMetricsData); } /** * 获取历史交通特征指数 * * @param request 请求参数,包含需要查询的历史交通特征指数的详细信息 * @return 返回一个AjaxResult对象,其中包含了查询结果的成功状态和历史交通特征指数数据列表 */ @ApiOperation("获取历史交通特征指数") @GetMapping("/history/metrics") public AjaxResult historyTrafficMetrics(DcTrafficMetricsDataRequest request){ // 调用服务层方法,查询历史交通特征指数数据 List dcTrafficMetricsDataList = dcTrafficSectionStatisticsService.historyTrafficMetrics(request); // 将查询结果封装成成功响应并返回 return AjaxResult.success(dcTrafficMetricsDataList); } /** * 获取当前拥堵路段 * * @param direction 交通方向,指定查询哪个方向的拥堵路段。具体方向的定义根据实际业务而定。 * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前拥堵路段的数据列表。 */ @ApiOperation("获取当前拥堵路段") @GetMapping("/current/congested") public AjaxResult currentCongestedSection(Byte direction){ // 调用服务层方法,获取当前交通指标数据 List dcTrafficMetricsData = dcTrafficSectionStatisticsService.currentCongestedSection(direction); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(dcTrafficMetricsData); } /** * 获取收费站统计数据 * * @param request 包含查询条件的请求对象,用于筛选历史收费站统计数据 * @return 返回一个AjaxResult对象,其中包含了查询到的收费站统计数据列表 */ @ApiOperation("获取收费站统计数据") @GetMapping("/history/toll-station") public AjaxResult historyTollStation(DcTollStationStatisticsData request){ // 调用服务层方法,根据请求条件查询历史车收费站数据 List dcStatisticsData = dcTollStationStatisticsDataService.tollStationData(request); // 将查询结果封装为成功响应并返回 return AjaxResult.success(dcStatisticsData); } /** * 获取累计车流量 * * @param request 包含查询条件的请求对象,用于筛选历史收费站统计数据 * @return 返回一个AjaxResult对象,其中包含了查询到的收费站统计数据列表 */ @ApiOperation("获取累计车流量") @GetMapping("/history/accumulated-flow") public AjaxResult accumulatedFlow(DcTollStationStatisticsData request){ // 调用服务层方法,根据请求条件查询历史车收费站数据 List dcStatisticsData = dcTollStationStatisticsDataService.accumulatedFlow(request); // 将查询结果封装为成功响应并返回 return AjaxResult.success(dcStatisticsData); } /** * 获取门架统计数据 * * @param request 包含查询条件的请求对象,用于筛选历史门架统计数据 * @return 返回一个AjaxResult对象,其中包含了查询到的门架统计数据列表 */ @ApiOperation("获取门架统计数据") @GetMapping("/history/gantry") public AjaxResult historyGantryData(DcGantryStatisticsData request){ // 调用服务层方法,根据请求条件查询历史车门架数据 List dcStatisticsData = dcGantryStatisticsDataService.gantryData(request); // 将查询结果封装为成功响应并返回 return AjaxResult.success(dcStatisticsData); } /** * 交通流统计 列表 * @param startDate * @param endDate * @param direction * @param periodType * @return */ @ApiOperation("交通流统计") @GetMapping("/history/trafficFlowStatistics") public TableDataInfo trafficFlowStatistics(String startDate, String endDate, String direction, String periodType){ startPage(); List> mapList = dcGantryStatisticsDataService.trafficFlowStatistics(startDate,endDate,direction,periodType); // 将查询结果封装为成功响应并返回 return getDataTable(mapList); } /** * 全路段双向实时车流量 * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 */ @ApiOperation("全路段车流量状况分析") @GetMapping("/history/realTimeTrafficFlow") public AjaxResult realTimeTrafficFlow(String startDate, String direction,String periodType ){ List> mapList = dcGantryStatisticsDataService.realTimeTrafficFlow(startDate,direction,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } /** * 导出全路段双向实时车流量 * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 */ @ApiOperation(value="导出全路段车流量状况分析",tags = {"ECharts导出"}) @GetMapping("/history/exportRealTimeTrafficFlow") public AjaxResult exportRealTimeTrafficFlow(HttpServletResponse response,String startDate, String direction,String periodType ){ if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(direction) || StringUtils.isEmpty(periodType)){ return AjaxResult.error("参数错误"); } String endDate = ""; if ("4".equals(periodType)){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate inputDate = LocalDate.parse(startDate, formatter); // 获取一年前的日期 LocalDate end = inputDate.minusYears(1); endDate = end.format(formatter); } else if ("3".equals(periodType)){ String[] parts = startDate.split("-"); int year = Integer.parseInt(parts[0]); int month = Integer.parseInt(parts[1]); // 计算一年前的年份和月份 year -= 1; // 如果计算后月份为0,则调整为上一年的12月 if (month == 0) { year -= 1; month = 12; } endDate = String.format("%04d-%02d", year, month); } else if ("1".equals(periodType)){ int year = Integer.parseInt(startDate) - 1; endDate = String.valueOf(year); } List list = new ArrayList<>(); List> mapList = dcGantryStatisticsDataService.realTimeTrafficFlow(startDate,direction,periodType); List> lastList = dcGantryStatisticsDataService.realTimeTrafficFlow(endDate,direction,periodType); mapList = mapList.stream().sorted( Comparator.comparing(map -> { String stakeMark = map.get("stake_make"); return StakeMarkUtils.formatMetre(stakeMark); })) .collect(Collectors.toList()); lastList = lastList.stream().sorted( Comparator.comparing(map -> { String stakeMark = map.get("stake_make"); return StakeMarkUtils.formatMetre(stakeMark); })) .collect(Collectors.toList()); for (int i = 0; i < mapList.size(); i++) { RealTimeTrafficFlow realTimeTrafficFlow = new RealTimeTrafficFlow(); realTimeTrafficFlow.setName(mapList.get(i).get("name")); realTimeTrafficFlow.setTotalPassengerFlow(String.valueOf(mapList.get(i).get("totalPassengerFlow"))); realTimeTrafficFlow.setTypeSpecialVehicleFlow(String.valueOf(mapList.get(i).get("typeSpecialVehicleFlow"))); realTimeTrafficFlow.setTypeTruckFlow(String.valueOf(mapList.get(i).get("typeTruckFlow"))); realTimeTrafficFlow.setLastYearTotal(String.valueOf(lastList.get(i).get("volume"))); list.add(realTimeTrafficFlow); } ExcelUtil util = new ExcelUtil<>(RealTimeTrafficFlow.class); util.exportExcel(response, list, "全路段双向实时车流量"); // 将查询结果封装为成功响应并返回 return AjaxResult.success("导出成功"); } /** * 车流量时段分析 * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 */ @ApiOperation("车流量时段分析") @GetMapping("/history/trafficPeriodAnalysis") public AjaxResult trafficPeriodAnalysis(String startDate, String direction,String periodType ){ List> mapList = dcGantryStatisticsDataService.trafficPeriodAnalysis(startDate,direction,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } /** * 导出车流量时段分析 * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 */ @ApiOperation(value="导出车流量时段分析",tags = {"ECharts导出"}) @GetMapping("/history/exportTrafficPeriodAnalysis") public AjaxResult exportTrafficPeriodAnalysis(HttpServletResponse response,String startDate, String direction,String periodType ){ if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(direction) || StringUtils.isEmpty(periodType)){ return AjaxResult.error("参数错误"); } String endDate = ""; if ("4".equals(periodType)){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate inputDate = LocalDate.parse(startDate, formatter); // 获取一年前的日期 LocalDate end = inputDate.minusYears(1); endDate = end.format(formatter); } else if ("3".equals(periodType)){ String[] parts = startDate.split("-"); int year = Integer.parseInt(parts[0]); int month = Integer.parseInt(parts[1]); // 计算一年前的年份和月份 year -= 1; // 如果计算后月份为0,则调整为上一年的12月 if (month == 0) { year -= 1; month = 12; } endDate = String.format("%04d-%02d", year, month); } else if ("1".equals(periodType)){ int year = Integer.parseInt(startDate) - 1; endDate = String.valueOf(year); } List list = new ArrayList<>(); List> mapList = dcGantryStatisticsDataService.trafficPeriodAnalysis(startDate,direction,periodType); Map mapData = new HashMap<>(); if (mapList != null && mapList.size() > 0){ for (Map item : mapList) { mapData.put(item.get("statisticalHour"),item.get("trafficVolume")); } } List> lastList = dcGantryStatisticsDataService.trafficPeriodAnalysis(endDate,direction,periodType); Map lastData = new HashMap<>(); if (lastList != null && lastList.size() > 0){ for (Map item : lastList) { lastData.put(item.get("statisticalHour"),item.get("trafficVolume")); } } for (int i = 0; i < 24; i++) { TrafficPeriodAnalysis trafficPeriodAnalysis = new TrafficPeriodAnalysis(); trafficPeriodAnalysis.setTime(i + "点至" + (i+1) + "点"); trafficPeriodAnalysis.setCurrentData(mapData.getOrDefault(String.valueOf(i), "0")); trafficPeriodAnalysis.setContemporaneousData(lastData.getOrDefault(String.valueOf(i), "0")); list.add(trafficPeriodAnalysis); } ExcelUtil util = new ExcelUtil<>(TrafficPeriodAnalysis.class); util.exportExcel(response, list, "车流量时段分析"); // 将查询结果封装为成功响应并返回 return AjaxResult.success("导出成功"); } @ApiOperation("断面车流量排名") @GetMapping("/history/sectionTrafficRanking") public AjaxResult sectionTrafficRanking(String startDate, String direction,String periodType ){ List> dcStatisticsData = dcGantryStatisticsDataService.sectionTrafficRanking(startDate,direction,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(dcStatisticsData); } /** * 导出断面车流量排名 * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 */ @ApiOperation(value="导出断面车流量排名",tags = {"ECharts导出"}) @GetMapping("/history/exportSectionTrafficRanking") public AjaxResult exportSectionTrafficRanking(HttpServletResponse response,String startDate, String direction,String periodType ){ List list = new ArrayList<>(); List> dcStatisticsData = dcGantryStatisticsDataService.sectionTrafficRanking(startDate,direction,periodType); for (int i = 0; i < dcStatisticsData.size(); i++) { SectionTrafficRanking sectionTrafficRanking = new SectionTrafficRanking(); sectionTrafficRanking.setRank(i + 1); sectionTrafficRanking.setFacilityName(dcStatisticsData.get(i).get("facilityName")); sectionTrafficRanking.setNumber(String.valueOf(dcStatisticsData.get(i).get("trafficVolume"))); list.add(sectionTrafficRanking); } ExcelUtil util = new ExcelUtil<>(SectionTrafficRanking.class); util.exportExcel(response, list, "断面车流量排名"); // 将查询结果封装为成功响应并返回 return AjaxResult.success("导出成功"); } /** * sectionTrafficIndexAnalysis * @param startDate 时间 * @param direction 方向 * @param periodType 时间粒子 * @param ranking 排名 1 饱和度 2拥挤度 3交通特征指数 * */ @ApiOperation("路段交通指标分析") @GetMapping("/history/sectionTrafficIndexAnalysis") public AjaxResult sectionTrafficIndexAnalysis(String startDate, String direction,String periodType,Long ranking ){ List> mapList = dcGantryMetricsStatisticsDataService.sectionTrafficIndexAnalysis(startDate,direction,periodType,ranking); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } @ApiOperation("通指标时间分布") @GetMapping("/history/passIndicatorTimeDistribution") public AjaxResult passIndicatorTimeDistribution(String startDate, String direction,String periodType ){ List> mapList = dcGantryMetricsStatisticsDataService.passIndicatorTimeDistribution(startDate,direction,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } @ApiOperation("交通指标雷达图") @GetMapping("/history/radarMapOfTrafficIndicators") public AjaxResult radarMapOfTrafficIndicators(String startDate, String direction,String periodType ){ Map map = dcGantryMetricsStatisticsDataService.radarMapOfTrafficIndicators(startDate,direction,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(map); } @ApiOperation("综合指标查询") @GetMapping("/history/comprehensiveIndexQuery") public TableDataInfo comprehensiveIndexQuery(ComprehensiveIndexQuery comprehensiveIndexQuery){ startPage(); List mapList = dcGantryMetricsStatisticsDataService.comprehensiveIndexQuery(comprehensiveIndexQuery); // 将查询结果封装为成功响应并返回 return getDataTable(mapList); } @ApiOperation("导出综合指标") //@PreAuthorize("@ss.hasPermi('system:event:export')") @Log(title = "导出综合指标", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, @RequestBody ComprehensiveIndexQuery comprehensiveIndexQuery) { List list = dcGantryMetricsStatisticsDataService.comprehensiveIndexQuery(comprehensiveIndexQuery); ExcelUtil util = new ExcelUtil(ComprehensiveIndexQuery.class); util.exportExcel(response, list, "事件信息数据"); } /** * 获取门架指标统计数据 * * @param request 包含查询条件的请求对象,用于筛选历史门架指标统计数据 * @return 返回一个AjaxResult对象,其中包含了查询到的门架指标统计数据列表 */ @ApiOperation("获取门架交通特指数数据") @GetMapping("/history/gantry-metrics") public AjaxResult historyGantryMetrics(DcGantryMetricsStatisticsData request){ // 调用服务层方法,根据请求条件查询历史车门架数据 List dcStatisticsData = dcGantryMetricsStatisticsDataService.gantryMetricsData(request); // 将查询结果封装为成功响应并返回 return AjaxResult.success(dcStatisticsData); } /********************************************* 智慧高速平接口 **************************************************/ /** * 获取在途车辆流量(分车型) * 该接口不接受任何参数,调用后返回在途车辆的统计数据,数据格式为JSONObject。 * * @return AjaxResult 返回类型为AjaxResult,其中包含了操作结果和在途车辆统计数据的JSONObject。 */ @ApiOperation("获取在途车辆流量(分车型)") @GetMapping("/current/in-transit-vehicles") public AjaxResult vehiclesInTransit() throws HttpException, IOException { // 调用服务层方法,获取在途车辆的统计数据 JSONArray dcStatisticsData = dcTrafficStatisticsService.vehiclesInTransit(); return AjaxResult.success(dcStatisticsData); } @ApiOperation("获取在途车路段平均车速") @GetMapping("/current/average-speed") public AjaxResult currentAverageSpeed() throws HttpException, IOException { // 调用服务层方法,获取在途车辆的统计数据 JSONArray dcStatisticsData = dcTrafficStatisticsService.currentAverageSpeed(); return AjaxResult.success(dcStatisticsData); } /** * 获取当前拥堵事件信息(智慧高速平台) * * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前拥堵路段的数据列表。 */ @ApiOperation("获取当前拥堵事件信息") @GetMapping("/current/event-congested") public AjaxResult currentEventCongested() throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 JSONArray jsonArray = dcTrafficStatisticsService.currentEventCongested(); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(jsonArray); } /** * 获取当前拥堵路段信息 * * @return 返回一个AjaxResult对象,其中包含了查询结果。如果查询成功,则结果中封装了当前拥堵路段的数据列表。 */ @ApiOperation("获取当前路段拥堵信息") @GetMapping("/current/section-congested") public AjaxResult currentSectionCongested() throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 List roadSectionCongestions = dcTrafficStatisticsService.currentSectionCongested(); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(roadSectionCongestions); } /** * 获取车道占有率信息 * */ @ApiOperation("获取车道占有率信息") @GetMapping("/history/lane-occupancy") public AjaxResult laneOccupancy(String startDate, String endDate) throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 JSONArray jsonArray = dcTrafficStatisticsService.laneOccupancy(startDate, endDate); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(jsonArray); } /** * 断面小时车流量分车型 */ @ApiOperation("断面小时车流量分车型") @GetMapping("/history/sectionHourlyTrafficFlow") public AjaxResult sectionHourlyTrafficFlow(String startDate, String endDate) throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 JSONArray jsonArray = dcTrafficStatisticsService.sectionHourlyTrafficFlow(startDate, endDate); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(jsonArray); }/** * 各收费站入口分车型车流量 */ @ApiOperation("各收费站入口分车型小时车流量") @GetMapping("/history/trafficFlowAtTollStationEntranceHour") public AjaxResult trafficFlowAtTollStationEntranceHour(String startDate, String endDate,String stationType) throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 List> jsonArray = dcTrafficStatisticsService.trafficFlowAtTollStationEntrance(startDate, endDate, stationType); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(jsonArray); } /** * 各收费站入口分车型小时车流量 */ @ApiOperation("各收费站入口分车型车流量") @GetMapping("/history/trafficFlowAtTollStationEntrance") public AjaxResult trafficFlowAtTollStationEntrance(String startDate, String endDate,String stationType) throws HttpException, IOException { // 调用服务层方法,获取当前交通指标数据 JSONArray jsonArray = dcTrafficStatisticsService.trafficFlowAtTollStationEntranceHour(startDate, endDate, stationType); // 将获取到的交通指标数据封装为成功的结果并返回 return AjaxResult.success(jsonArray); } /** * 全路段双向实时车流量 * @param startDate 时间 * @param direction 方向 */ @ApiOperation("全路段双向实时车流量") @GetMapping("/history/realTimeTrafficFlowHour") public AjaxResult realTimeTrafficFlowHour(String startDate,Long direction) throws HttpException, IOException{ List> mapList = dcTrafficStatisticsService.realTimeTrafficFlowHour(startDate,direction); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } /** * 获取据库中 收费站统计数据 * @param startDate 时间 * @param accessType 出入口 1入 2出 * @param periodType 方向 */ @ApiOperation("获取据库中收费站数数据") @GetMapping("/history/TollBoothStatistics") public AjaxResult TollBoothStatistics(String startDate,String accessType,String periodType) throws HttpException, IOException{ List> mapList = dcTollStationStatisticsDataService.TollBoothStatistics(startDate,accessType,periodType); // 将查询结果封装为成功响应并返回 return AjaxResult.success(mapList); } }