diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 9d288e65..046648e7 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -69,7 +69,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public boolean matches(HttpServletRequest request) {
// 获取请求的IP
- String requestIP = request.getRemoteAddr();
+ String requestIP = request.getHeader("X-Forwarded-For");
// 将配置文件中的IP字符串分割为数组
String[] ips = allowedIPs.split(",");
// 检查请求的IP是否在允许的IP数组中
diff --git a/zc-business/pom.xml b/zc-business/pom.xml
index c0017e0b..6b870a73 100644
--- a/zc-business/pom.xml
+++ b/zc-business/pom.xml
@@ -47,6 +47,31 @@
com.ruoyi
ruoyi-system
+
+
+ org.apache.poi
+ poi-ooxml
+ 4.1.2
+
+
+ org.apache.poi
+ poi-ooxml-schemas
+ 4.1.2
+
+
+ org.apache.poi
+ poi
+ 4.1.2
+
+
+
+
+ com.deepoove
+ poi-tl
+ 1.9.1
+
+
com.zc
1.0.0
diff --git a/zc-business/src/main/java/com/zc/business/constant/RedisKeyConstants.java b/zc-business/src/main/java/com/zc/business/constant/RedisKeyConstants.java
index abeba97b..003a8ab5 100644
--- a/zc-business/src/main/java/com/zc/business/constant/RedisKeyConstants.java
+++ b/zc-business/src/main/java/com/zc/business/constant/RedisKeyConstants.java
@@ -10,4 +10,23 @@ public class RedisKeyConstants
* 设备
*/
public static final String DC_DEVICES = "dc:devices";
+
+ /**
+ * 路段
+ */
+ public static final String DC_ROAD_SECTION = "dc:roadSection";
+
+ /**
+ * 设备实时交通统计
+ */
+ private static final String DC_DEVICES_TRAFFIC_STATISTICS = "dc:devicesTrafficStatistics";
+
+ /**
+ * 获取实时交通统计key
+ * @param direction 方向
+ * @return key
+ */
+ public static String getDcDevicesTrafficStatisticsKey(Byte direction) {
+ return DC_DEVICES_TRAFFIC_STATISTICS + ":" + direction;
+ }
}
diff --git a/zc-business/src/main/java/com/zc/business/constant/StakeMarkConstant.java b/zc-business/src/main/java/com/zc/business/constant/StakeMarkConstant.java
new file mode 100644
index 00000000..45d5e654
--- /dev/null
+++ b/zc-business/src/main/java/com/zc/business/constant/StakeMarkConstant.java
@@ -0,0 +1,27 @@
+package com.zc.business.constant;
+
+/**
+ * StakeMarkConstant类,用于定义一些桩号常量。
+ * @author xiepufeng
+ */
+public class StakeMarkConstant {
+
+
+ // 定义最大桩号常量
+ public static final int MAX_STAKE_MARK = 208979;
+
+ // 定义最小桩号常量
+ public static final int MIN_STAKE_MARK = 54394;
+
+ // 定义毫米波雷达最大测量间隔
+ public static final int MAX_INTERVAL_MILLIMETER_WAVE_RADAR = 12030;
+
+ /**
+ * 计算道路长度
+ * @return 道路长度(单位:米)
+ */
+ public static int calculateRoadLength() {
+ return MAX_STAKE_MARK - MIN_STAKE_MARK;
+ }
+
+}
diff --git a/zc-business/src/main/java/com/zc/business/constant/StatisticalRecoveryOffsetTime.java b/zc-business/src/main/java/com/zc/business/constant/StatisticalRecoveryOffsetTime.java
deleted file mode 100644
index 78117d8d..00000000
--- a/zc-business/src/main/java/com/zc/business/constant/StatisticalRecoveryOffsetTime.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.zc.business.constant;
-
-/**
- * 统计恢复偏移时间类
- * 用于定义与交通数据恢复相关的偏移时间常量。
- *
- * @author xiepufeng
- */
-public class StatisticalRecoveryOffsetTime {
-
- // 定义交通数据段偏移的天数常量,表示偏移-10天
- public static final int TRAFFIC_SECTION_DATA_OFFSET_DAY = -10;
-}
-
diff --git a/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java
new file mode 100644
index 00000000..828e8712
--- /dev/null
+++ b/zc-business/src/main/java/com/zc/business/controller/DcTrafficStatisticsController.java
@@ -0,0 +1,60 @@
+package com.zc.business.controller;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.zc.business.domain.DcTrafficMetricsData;
+import com.zc.business.request.DcTrafficMetricsDataRequest;
+import com.zc.business.service.DcTrafficStatisticsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 交通数据统计
+ *
+ * @author xiepufeng
+ */
+@Api(tags = "交通数据统计")
+@RestController
+@RequestMapping("/business/traffic-statistics")
+public class DcTrafficStatisticsController {
+
+ @Autowired
+ private DcTrafficStatisticsService dcTrafficStatisticsService;
+
+
+ /**
+ * 获取当前交通特征指数
+ *
+ * @param request 请求参数,封装了获取交通指标所需的数据和条件
+ * @return 返回当前交通特征指数的数据结果,使用AjaxResult包装
+ */
+ @ApiOperation("获取当前交通特征指数")
+ @GetMapping("/current/metrics")
+ public AjaxResult currentTrafficMetrics(DcTrafficMetricsDataRequest request){
+ // 调用服务层方法,获取当前交通指标数据
+ DcTrafficMetricsData dcTrafficMetricsData = dcTrafficStatisticsService.currentTrafficMetrics(request);
+ // 将获取到的交通指标数据封装为成功的结果并返回
+ return AjaxResult.success(dcTrafficMetricsData);
+ }
+
+ /**
+ * 获取历史交通特征指数
+ *
+ * @param request 请求参数,包含需要查询的历史交通特征指数的详细信息
+ * @return 返回一个AjaxResult对象,其中包含了查询结果的成功状态和历史交通特征指数数据列表
+ */
+ @ApiOperation("获取历史交通特征指数")
+ @GetMapping("/history/metrics")
+ public AjaxResult historyTrafficMetrics(DcTrafficMetricsDataRequest request){
+ // 调用服务层方法,查询历史交通特征指数数据
+ List dcTrafficMetricsDataList = dcTrafficStatisticsService.historyTrafficMetrics(request);
+ // 将查询结果封装成成功响应并返回
+ return AjaxResult.success(dcTrafficMetricsDataList);
+ }
+
+}
diff --git a/zc-business/src/main/java/com/zc/business/controller/VideoController.java b/zc-business/src/main/java/com/zc/business/controller/VideoController.java
index 86d3a73f..2021f8a4 100644
--- a/zc-business/src/main/java/com/zc/business/controller/VideoController.java
+++ b/zc-business/src/main/java/com/zc/business/controller/VideoController.java
@@ -9,8 +9,8 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.zc.business.constant.DeviceTypeConstants;
import com.zc.business.domain.DcDevice;
-import com.zc.business.enums.CameraDirection;
-import com.zc.business.enums.LaneDirection;
+import com.zc.business.enums.CameraDirectionEnum;
+import com.zc.business.enums.LaneDirectionEnum;
import com.zc.business.service.IDcDeviceService;
import com.zc.business.service.IMiddleDatabaseService;
import com.zc.common.core.httpclient.OkHttp;
@@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
@@ -121,12 +120,12 @@ public class VideoController extends BaseController {
String pileNum = cameraInfo.getString("pileNum");
// 方向
Integer camOrientation = cameraInfo.getInteger("camOrientation");
- LaneDirection laneDirection = CameraDirection.fromCode(camOrientation).toLaneDirection();
+ LaneDirectionEnum laneDirectionEnum = CameraDirectionEnum.fromCode(camOrientation).toLaneDirection();
// 是否有云台控制 0 有(球机) 1 ⽆(枪机)
String ptzCtrl = cameraInfo.getString("ptzCtrl");
- String key = pileNum + "|" + laneDirection.getValue() + "|" + ptzCtrl;
+ String key = pileNum + "|" + laneDirectionEnum.getValue() + "|" + ptzCtrl;
if (cameraMap.containsKey(key)) {
DcDevice dcDevice = cameraMap.get(key);
diff --git a/zc-business/src/main/java/com/zc/business/controller/WordController.java b/zc-business/src/main/java/com/zc/business/controller/WordController.java
new file mode 100644
index 00000000..b2879914
--- /dev/null
+++ b/zc-business/src/main/java/com/zc/business/controller/WordController.java
@@ -0,0 +1,1050 @@
+package com.zc.business.controller;
+
+import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.zc.business.mapper.DcTrafficIncidentsMapper;
+import com.zc.business.utils.PoiUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xwpf.usermodel.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.text.SimpleDateFormat;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+import static com.zc.business.utils.PoiUtil.*;
+
+/**
+ * @Description 通行情况快报
+ *
+ * @author liuwenge
+ * @date 2024/3/26 11:13
+ */
+@Api(tags = "通行情况快报")
+@RestController
+@RequestMapping("/business/word")
+public class WordController {
+
+ @Autowired
+ private WeatherForecastController weatherForecastController;
+ @Autowired
+ private DcTrafficIncidentsMapper dcTrafficIncidentsMapper;
+
+
+ @PostMapping("/trafficSituationReport")
+ @ApiOperation("导出通行情况快报")
+ public void trafficSituationReport(HttpServletResponse response){
+ try {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ String date = df.format(new Date());
+ String outputPath = RuoYiConfig.getDownloadPath() +"/济菏高速公路通行情况快报" + date + ".docx";
+ // 读取Word模板
+ InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("wordTemplate/wordTemplate.docx");
+ XWPFDocument newDoc = new XWPFDocument(inputStream);
+
+ // 创建并插入带超链接的目录
+ insertTOC(newDoc);
+
+
+ //换页
+ XWPFParagraph breakPara = newDoc.createParagraph();
+ breakPara.setAlignment(ParagraphAlignment.CENTER);
+ CTP ctP = breakPara.getCTP();
+ CTR ctr = ctP.addNewR();
+ CTBr ctBr = ctr.addNewBr();
+ ctBr.setType(STBrType.PAGE);
+
+
+
+ PoiUtil.createHeading1(newDoc,"总体情况");
+ /** 天气情况统计 */
+ weather(newDoc);
+ /** 交通管制情况 */
+ trafficControl(newDoc);
+ /** 交通事故 */
+ trafficAccident(newDoc);
+ /** 出入口车流量 */
+ trafficFlow(newDoc);
+
+
+
+ PoiUtil.createHeading1(newDoc,"收费站运行情况");
+ /** 封闭原因统计 */
+ trafficControlReasons(newDoc);
+ /** 封闭数量统计 */
+ closedQuantity(newDoc);
+ PoiUtil.createHeading1(newDoc,"交通事故情况");
+ /** 交通事故统计 */
+ accidentType(newDoc);
+
+
+ PoiUtil.createHeading1(newDoc,"拥堵情况");
+ /** 拥堵地点 */
+ congestionLocation(newDoc);
+ /** 拥堵时长 */
+ congestionDuration(newDoc);
+ /** 拥堵长度 */
+ congestionMileage(newDoc);
+
+
+
+ // 保存新生成的Word文件
+// FileOutputStream out = new FileOutputStream(outputPath);
+// out.close();
+
+ // 不保存直接返回文件流
+ newDoc.write(response.getOutputStream());
+
+
+ // 关闭文档
+ newDoc.close();
+ System.out.println("生成通行情况快报成功!");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @Description 天气情况统计
+ *
+ * @author liuwenge
+ * @date 2024/3/26 15:39
+ * @param
+ * @return void
+ */
+
+ public void weather(XWPFDocument doc) {
+
+ PoiUtil.createHeading2(doc,"天气情况统计");
+
+ XWPFTable table = doc.createTable(9, 25);
+ //列宽自动分割
+ CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
+ infoTableWidth.setType(STTblWidth.DXA);
+ infoTableWidth.setW(BigInteger.valueOf(9072));
+
+ AjaxResult ajaxResult = weatherForecastController.hourlyWeather();
+ if (ajaxResult.get("code").equals(200)) {
+ Map>> data = (Map>>) ajaxResult.get("data");
+ data.keySet().forEach(key ->{
+ if ("hourlyWeather1".equals(key)){
+ setTableFonts(table.getRow(1).getCell(0), "长清区");
+ List