浏览代码

Merge remote-tracking branch 'origin/master'

15044148858 2 周之前
父节点
当前提交
396ad5e623
共有 100 个文件被更改,包括 6357 次插入130 次删除
  1. 44 0
      construction-ui/src/api/construction/evaluation/evaluation.js
  2. 44 0
      construction-ui/src/api/construction/riskregister/gasinspectionreformanalysis.js
  3. 44 0
      construction-ui/src/api/construction/riskregister/monitor.js
  4. 44 0
      construction-ui/src/api/construction/riskregister/pipedamagestats.js
  5. 44 0
      construction-ui/src/api/construction/riskregister/satisfaction.js
  6. 44 0
      construction-ui/src/api/construction/riskregister/smartcoveragerate.js
  7. 44 0
      construction-ui/src/api/construction/riskregister/wateranalysis.js
  8. 44 0
      construction-ui/src/api/construction/supervision/log.js
  9. 53 0
      construction-ui/src/api/construction/supervision/supervision.js
  10. 341 0
      construction-ui/src/views/construction/evaluation/index.vue
  11. 8 0
      construction-ui/src/views/construction/gas/station/index.vue
  12. 2 2
      construction-ui/src/views/construction/gas_task/index.vue
  13. 22 3
      construction-ui/src/views/construction/heating/report/index.vue
  14. 334 0
      construction-ui/src/views/construction/riskregister/gasinspectionreformanalysis/index.vue
  15. 322 0
      construction-ui/src/views/construction/riskregister/monitor/index.vue
  16. 348 0
      construction-ui/src/views/construction/riskregister/pipedamagestats/index.vue
  17. 323 0
      construction-ui/src/views/construction/riskregister/satisfaction/index.vue
  18. 302 0
      construction-ui/src/views/construction/riskregister/smartcoveragerate/index.vue
  19. 286 0
      construction-ui/src/views/construction/riskregister/wateranalysis/index.vue
  20. 532 0
      construction-ui/src/views/construction/supervision/index.vue
  21. 364 0
      construction-ui/src/views/construction/supervision/log/index.vue
  22. 4 4
      construction-ui/src/views/construction/utilityTunnel/pipe/index.vue
  23. 6 0
      package-lock.json
  24. 251 0
      src/main/java/com/sooka/sponest/construction/api/PlatformBridge.java
  25. 463 85
      src/main/java/com/sooka/sponest/construction/api/PlatformDeviceApi.java
  26. 29 0
      src/main/java/com/sooka/sponest/construction/api/PlatformRiskRegister.java
  27. 621 0
      src/main/java/com/sooka/sponest/construction/api/PlatformUtilityTunnel.java
  28. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/BurialYearTypeCountVO.java
  29. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/CasingShapeMatCountVO.java
  30. 18 0
      src/main/java/com/sooka/sponest/construction/api/vo/ConstructionYearBridgeTotalLengthVO.java
  31. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/ConstructionYearStructureCountVO.java
  32. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/CoverManholeMaterialCountVO.java
  33. 22 0
      src/main/java/com/sooka/sponest/construction/api/vo/CrossLenByRegionVO.java
  34. 15 0
      src/main/java/com/sooka/sponest/construction/api/vo/DefectScopeCountByTypeVO.java
  35. 13 0
      src/main/java/com/sooka/sponest/construction/api/vo/DeviceEventAlarmVO.java
  36. 19 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictCoverShapeMatCountVO.java
  37. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictDangerTypeCountVO.java
  38. 20 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictDefectTypeCountVO.java
  39. 19 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictPierCountByTypeVO.java
  40. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictPipeMaterialCountVO.java
  41. 20 0
      src/main/java/com/sooka/sponest/construction/api/vo/DistrictStructureCountVO.java
  42. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/DivCatUtilityTunnelCountVO.java
  43. 40 0
      src/main/java/com/sooka/sponest/construction/api/vo/EChartsBarLineChartVO.java
  44. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/InstallDateChamberSpecCountVO.java
  45. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/MaterialPressureLevelPipeCountVO.java
  46. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/MaterialProtectionMatPipeCountVO.java
  47. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/ReportActualFixDateVO.java
  48. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/StreetCommHouseCountVO.java
  49. 18 0
      src/main/java/com/sooka/sponest/construction/api/vo/StructureTypeBridgeTotalLengthVO.java
  50. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/UtPressureCountByBuriedTypeVO.java
  51. 17 0
      src/main/java/com/sooka/sponest/construction/api/vo/UtilityTunnelMatCountByTypeVO.java
  52. 15 0
      src/main/java/com/sooka/sponest/construction/api/vo/YearUtPipeAgeCountVO.java
  53. 8 0
      src/main/java/com/sooka/sponest/construction/bridge/domain/BridgeInspectionTaskRecord.java
  54. 6 0
      src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeAllyCrossPierMapper.java
  55. 7 0
      src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeCheckDiseaseMapper.java
  56. 3 0
      src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeDeviceMapper.java
  57. 12 0
      src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeInfoMapper.java
  58. 4 0
      src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeInspectionTaskRecordMapper.java
  59. 6 0
      src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeAllyCrossPierService.java
  60. 7 0
      src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeCheckDiseaseService.java
  61. 3 0
      src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeDeviceService.java
  62. 12 0
      src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeInfoService.java
  63. 13 0
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeAllyCrossPierServiceImpl.java
  64. 13 0
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeCheckDiseaseServiceImpl.java
  65. 2 2
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeDeviceMonitoringServiceImpl.java
  66. 7 0
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeDeviceServiceImpl.java
  67. 24 0
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeInfoServiceImpl.java
  68. 23 7
      src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgePipeInspectionTaskServiceImpl.java
  69. 7 0
      src/main/java/com/sooka/sponest/construction/community/mapper/BuildingMapper.java
  70. 7 0
      src/main/java/com/sooka/sponest/construction/community/service/IBuildingService.java
  71. 13 0
      src/main/java/com/sooka/sponest/construction/community/service/impl/BuildingServiceImpl.java
  72. 8 0
      src/main/java/com/sooka/sponest/construction/drainage/domain/DrainageInspectionTaskRecord.java
  73. 4 0
      src/main/java/com/sooka/sponest/construction/drainage/mapper/DrainageDeviceBaseInfoDataMapper.java
  74. 3 0
      src/main/java/com/sooka/sponest/construction/drainage/mapper/DrainageInspectionTaskRecordMapper.java
  75. 3 0
      src/main/java/com/sooka/sponest/construction/drainage/service/IDrainageDeviceBaseInfoDataService.java
  76. 7 0
      src/main/java/com/sooka/sponest/construction/drainage/service/impl/DrainageDeviceBaseInfoDataServiceImpl.java
  77. 21 8
      src/main/java/com/sooka/sponest/construction/drainage/service/impl/DrainagePipeInspectionTaskServiceImpl.java
  78. 91 0
      src/main/java/com/sooka/sponest/construction/evaluation/controller/PerformanceEvaluationController.java
  79. 57 0
      src/main/java/com/sooka/sponest/construction/evaluation/domain/PerformanceEvaluation.java
  80. 62 0
      src/main/java/com/sooka/sponest/construction/evaluation/mapper/PerformanceEvaluationMapper.java
  81. 62 0
      src/main/java/com/sooka/sponest/construction/evaluation/service/IPerformanceEvaluationService.java
  82. 142 0
      src/main/java/com/sooka/sponest/construction/evaluation/service/impl/PerformanceEvaluationServiceImpl.java
  83. 8 0
      src/main/java/com/sooka/sponest/construction/gas/domain/GasInspectionTaskRecord.java
  84. 5 0
      src/main/java/com/sooka/sponest/construction/gas/domain/GasStation.java
  85. 4 0
      src/main/java/com/sooka/sponest/construction/gas/mapper/GasDeviceBaseInfoDataMapper.java
  86. 3 0
      src/main/java/com/sooka/sponest/construction/gas/mapper/GasInspectionTaskRecordMapper.java
  87. 3 0
      src/main/java/com/sooka/sponest/construction/gas/service/IGasDeviceBaseInfoDataService.java
  88. 6 0
      src/main/java/com/sooka/sponest/construction/gas/service/impl/GasDeviceBaseInfoDataServiceImpl.java
  89. 21 7
      src/main/java/com/sooka/sponest/construction/gas/service/impl/GasPipeInspectionTaskServiceImpl.java
  90. 8 0
      src/main/java/com/sooka/sponest/construction/heating/domain/HeatingInspectionTaskRecord.java
  91. 2 0
      src/main/java/com/sooka/sponest/construction/heating/domain/HeatingMaintenanceReport.java
  92. 3 0
      src/main/java/com/sooka/sponest/construction/heating/mapper/HeatingDeviceMapper.java
  93. 3 0
      src/main/java/com/sooka/sponest/construction/heating/mapper/HeatingInspectionTaskRecordMapper.java
  94. 3 0
      src/main/java/com/sooka/sponest/construction/heating/service/IHeatingDeviceService.java
  95. 7 0
      src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingDeviceServiceImpl.java
  96. 42 5
      src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingMaintenanceReportServiceImpl.java
  97. 21 7
      src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingPipeInspectionTaskServiceImpl.java
  98. 128 0
      src/main/java/com/sooka/sponest/construction/operateSystem/controller/OperateController.java
  99. 33 0
      src/main/java/com/sooka/sponest/construction/operateSystem/domain/Operate.java
  100. 0 0
      src/main/java/com/sooka/sponest/construction/operateSystem/mapper/OperateMapper.java

+ 44 - 0
construction-ui/src/api/construction/evaluation/evaluation.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询考核评价列表
+export function listEvaluation(query) {
+  return request({
+    url: '/sooka-digital-construction/evaluation/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询考核评价详细
+export function getEvaluation(id) {
+  return request({
+    url: '/sooka-digital-construction/evaluation/' + id,
+    method: 'get'
+  })
+}
+
+// 新增考核评价
+export function addEvaluation(data) {
+  return request({
+    url: '/sooka-digital-construction/evaluation',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改考核评价
+export function updateEvaluation(data) {
+  return request({
+    url: '/sooka-digital-construction/evaluation',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除考核评价
+export function delEvaluation(id) {
+  return request({
+    url: '/sooka-digital-construction/evaluation/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/gasinspectionreformanalysis.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询燃气查改分析数据列表
+export function listGasinspectionreformanalysis(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/gasinspectionreformanalysis/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询燃气查改分析数据详细
+export function getGasinspectionreformanalysis(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/gasinspectionreformanalysis/' + id,
+    method: 'get'
+  })
+}
+
+// 新增燃气查改分析数据
+export function addGasinspectionreformanalysis(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/gasinspectionreformanalysis',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改燃气查改分析数据
+export function updateGasinspectionreformanalysis(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/gasinspectionreformanalysis',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除燃气查改分析数据
+export function delGasinspectionreformanalysis(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/gasinspectionreformanalysis/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/monitor.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询管网智能化监测列表
+export function listMonitor(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/monitor/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询管网智能化监测详细
+export function getMonitor(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/monitor/' + id,
+    method: 'get'
+  })
+}
+
+// 新增管网智能化监测
+export function addMonitor(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/monitor',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改管网智能化监测
+export function updateMonitor(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/monitor',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除管网智能化监测
+export function delMonitor(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/monitor/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/pipedamagestats.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询管道破损统计数据列表
+export function listPipedamagestats(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/pipedamagestats/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询管道破损统计数据详细
+export function getPipedamagestats(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/pipedamagestats/' + id,
+    method: 'get'
+  })
+}
+
+// 新增管道破损统计数据
+export function addPipedamagestats(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/pipedamagestats',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改管道破损统计数据
+export function updatePipedamagestats(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/pipedamagestats',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除管道破损统计数据
+export function delPipedamagestats(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/pipedamagestats/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/satisfaction.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询危旧桥梁满意度调查数据列表
+export function listSatisfaction(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/satisfaction/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询危旧桥梁满意度调查数据详细
+export function getSatisfaction(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/satisfaction/' + id,
+    method: 'get'
+  })
+}
+
+// 新增危旧桥梁满意度调查数据
+export function addSatisfaction(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/satisfaction',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改危旧桥梁满意度调查数据
+export function updateSatisfaction(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/satisfaction',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除危旧桥梁满意度调查数据
+export function delSatisfaction(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/satisfaction/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/smartcoveragerate.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询普查覆盖率列表
+export function listSmartcoveragerate(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/smartcoveragerate/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询普查覆盖率详细
+export function getSmartcoveragerate(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/smartcoveragerate/' + id,
+    method: 'get'
+  })
+}
+
+// 新增普查覆盖率
+export function addSmartcoveragerate(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/smartcoveragerate',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改普查覆盖率
+export function updateSmartcoveragerate(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/smartcoveragerate',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除普查覆盖率
+export function delSmartcoveragerate(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/smartcoveragerate/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/riskregister/wateranalysis.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询居民用水分析数据列表
+export function listWateranalysis(query) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/wateranalysis/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询居民用水分析数据详细
+export function getWateranalysis(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/wateranalysis/' + id,
+    method: 'get'
+  })
+}
+
+// 新增居民用水分析数据
+export function addWateranalysis(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/wateranalysis',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改居民用水分析数据
+export function updateWateranalysis(data) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/wateranalysis',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除居民用水分析数据
+export function delWateranalysis(id) {
+  return request({
+    url: '/sooka-digital-construction/riskregister/wateranalysis/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
construction-ui/src/api/construction/supervision/log.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询监管日志列表
+export function listLog(query) {
+  return request({
+    url: '/sooka-digital-construction/log/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询监管日志详细
+export function getLog(id) {
+  return request({
+    url: '/sooka-digital-construction/log/' + id,
+    method: 'get'
+  })
+}
+
+// 新增监管日志
+export function addLog(data) {
+  return request({
+    url: '/sooka-digital-construction/log',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改监管日志
+export function updateLog(data) {
+  return request({
+    url: '/sooka-digital-construction/log',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除监管日志
+export function delLog(id) {
+  return request({
+    url: '/sooka-digital-construction/log/' + id,
+    method: 'delete'
+  })
+}

+ 53 - 0
construction-ui/src/api/construction/supervision/supervision.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询工地监管列表
+export function listSupervision(query) {
+  return request({
+    url: '/sooka-digital-construction/supervision/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询工地监管详细
+export function getSupervision(id) {
+  return request({
+    url: '/sooka-digital-construction/supervision/' + id,
+    method: 'get'
+  })
+}
+
+// 新增工地监管
+export function addSupervision(data) {
+  return request({
+    url: '/sooka-digital-construction/supervision',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改工地监管
+export function updateSupervision(data) {
+  return request({
+    url: '/sooka-digital-construction/supervision',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除工地监管
+export function delSupervision(id) {
+  return request({
+    url: '/sooka-digital-construction/supervision/' + id,
+    method: 'delete'
+  })
+}
+
+// 查询摄像头列表
+export function selectCenterMonitorlList(query) {
+  return request({
+    url: '/sooka-sponest-center-monitor/centerMonitorFeign/remoteList',
+    method: 'post',
+    data: query
+  })
+}

+ 341 - 0
construction-ui/src/views/construction/evaluation/index.vue

@@ -0,0 +1,341 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"
+             @submit.native.prevent>
+      <el-form-item label="标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入标题"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['evaluation:evaluation:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['evaluation:evaluation:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['evaluation:evaluation:remove']"
+        >删除
+        </el-button>
+      </el-col>
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="warning"-->
+<!--          plain-->
+<!--          icon="el-icon-download"-->
+<!--          size="mini"-->
+<!--          @click="handleExport"-->
+<!--          v-hasPermi="['evaluation:evaluation:export']"-->
+<!--        >导出-->
+<!--        </el-button>-->
+<!--      </el-col>-->
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="evaluationList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="标题" align="center" prop="title"/>
+      <el-table-column label="内容" align="center" prop="content"/>
+      <el-table-column label="考核周期" align="center" prop="cycle"/>
+      <el-table-column label="所属公司" align="center" prop="deptName"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['evaluation:evaluation:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['evaluation:evaluation:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改考核评价对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" class="form-style">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入标题" maxlength="32"/>
+        </el-form-item>
+        <el-form-item label="考核周期" prop="cycle">
+          <el-date-picker v-model="form.cycle" clearable
+                          placeholder="请选择敷设日期"
+                          size="small"
+                          type="date"
+                          value-format="yyyy-MM-dd">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="内容">
+          <el-input v-model="form.content" placeholder="请输入内容" maxlength="50"/>
+        </el-form-item>
+        <el-form-item label="所属公司" prop="deptId">
+          <treeselect v-model="form.deptId" :noOptionsText="'空'" :noResultsText="'空'"
+                      :options="deptOptions"
+                      :show-count="true" multiple:false placeholder="请选择公司" @select="hx"/>
+        </el-form-item>
+        <el-form-item label="附件" prop="fileUrl">
+          <fileUpload v-model="form.fileUrl" :limit="1" :removeFileName="removeFileName"
+                      :setFileName="setFileName"></fileUpload>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addEvaluation,
+  delEvaluation,
+  getEvaluation,
+  listEvaluation,
+  updateEvaluation
+} from "@/api/construction/evaluation/evaluation";
+import {treeselectAll} from "@/api/system/dept";
+import Treeselect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import FileUpload from "@/views/components/FileUpload/index.vue";
+
+export default {
+  name: "Evaluation",
+  components: {Treeselect,FileUpload},
+  data() {
+    return {
+      fileNames: [],
+      // 部门树选项
+      deptOptions: undefined,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 考核评价表格数据
+      evaluationList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        title: null,
+        content: null,
+        cycle: null,
+        fileUrl: null,
+        fileName: null,
+        createName: null,
+        updateName: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        title: [
+          {required: true, message: "标题不能为空", trigger: "change"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getTreeSelect()
+  },
+  methods: {
+    /** 附件:文件 **/
+    setFileName(fileName) {
+      this.fileNames.push(fileName)
+    },
+    removeFileName(index) {
+      this.fileNames.splice(index, 1);
+      let fileurls = this.form.fileUrl.split(",")
+      fileurls.splice(index, 1)
+      this.form.fileUrl = fileurls.toString()
+    },
+    /** 查询部门下拉树结构 */
+    getTreeSelect() {
+      treeselectAll().then(response => {
+        this.deptOptions = response.data;
+      });
+    },
+    hx(node) {
+      this.form.dataDeptId = node.id
+      this.form.deptId = node.id
+      this.form.deptName = node.label
+      this.$refs.form.validateField("deptId")
+    },
+    /** 查询考核评价列表 */
+    getList() {
+      this.loading = true;
+      listEvaluation(this.queryParams).then(response => {
+        this.evaluationList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        title: null,
+        content: null,
+        cycle: null,
+        fileUrl: null,
+        fileName: null,
+        createBy: null,
+        createName: null,
+        createTime: null,
+        updateBy: null,
+        updateName: null,
+        updateTime: null
+      };
+      this.fileNames = []
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加考核评价";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getEvaluation(id).then(response => {
+        if (response.data.fileUrl !== "" && response.data.fileUrl != null) {
+          const list = response.data.fileUrl.split(',');
+          for (var a = 0; a < list.length; a++) {
+            let listurl = list[a].split('+')
+            this.fileNames.push(listurl[1])
+          }
+        }
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改考核评价";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.form.fileName = this.fileNames.toString()
+          if (this.form.id != null) {
+            updateEvaluation(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addEvaluation(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除考核评价编号为"' + ids + '"的数据项?').then(function () {
+        return delEvaluation(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('evaluation/evaluation/export', {
+        ...this.queryParams
+      }, `evaluation_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 8 - 0
construction-ui/src/views/construction/gas/station/index.vue

@@ -135,6 +135,14 @@
             <el-form-item label="地址" prop="address">
               <el-input v-model="form.address" maxlength="32" placeholder="请输入地址"/>
             </el-form-item>
+            <el-form-item label="出厂日期" prop="manufacturingDate">
+            <el-date-picker v-model="form.manufacturingDate" clearable
+                            placeholder="请选择出厂日期"
+                            size="small"
+                            type="date"
+                            value-format="yyyy-MM-dd">
+            </el-date-picker>
+            </el-form-item>
             <el-form-item label="场站类型" prop="stationType">
               <el-select v-model="form.stationType" placeholder="请选择住户类型">
                 <el-option

+ 2 - 2
construction-ui/src/views/construction/gas_task/index.vue

@@ -179,7 +179,7 @@
           <el-input v-model="form.inspectionCycle" maxlength="5" placeholder="请输入巡检周期"/>
         </el-form-item>
         <el-form-item label="燃气管线" prop="pipeId">
-          <el-select v-model="form.pipeId" multiple placeholder="请选择燃气管线" @change="$forceUpdate();">
+          <el-select v-model="form.pipeId" multiple filterable placeholder="请选择燃气管线" @change="$forceUpdate();">
             <el-option
               v-for="dict in gasPipeList"
               :key="dict.id"
@@ -189,7 +189,7 @@
           </el-select>
         </el-form-item>
         <el-form-item label="巡检人" prop="userId">
-          <el-select v-model="form.userId" multiple placeholder="请选择巡检人" @change="$forceUpdate();">
+          <el-select v-model="form.userId" multiple filterable placeholder="请选择巡检人" @change="$forceUpdate();">
             <el-option
               v-for="dict in userList"
               :key="dict.userId"

+ 22 - 3
construction-ui/src/views/construction/heating/report/index.vue

@@ -142,7 +142,7 @@
           <el-input v-model="form.reportRemark" maxlength="100" placeholder="请输入描述" type="textarea"/>
         </el-form-item>
         <el-form-item label="附件">
-          <file-upload v-model="form.reportUrl" :limit="1"/>
+          <fileUpload v-model="form.reportUrl" :limit="1" :removeFileName="removeFileName" :setFileName="setFileName"></fileUpload>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -158,10 +158,11 @@ import {addReport, delReport, getReport, listReport, updateReport} from "@/api/c
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import Treeselect from "@riophae/vue-treeselect";
 import {treeselectAll} from "@/api/system/dept";
+import FileUpload from '@/views/components/FileUpload/index.vue'
 
 export default {
   name: "Report",
-  components: {Treeselect},
+  components: {Treeselect,FileUpload},
   dicts: ['lifeline_enterprise', 'lifeline_industry'],
   data() {
     return {
@@ -197,7 +198,9 @@ export default {
       // 部门树选项
       deptOptions: undefined,
       // 表单参数
-      form: {},
+      form: {
+        fileName:''
+      },
       // 表单校验
       rules: {
         reportName: [
@@ -210,6 +213,14 @@ export default {
     this.getList();
   },
   methods: {
+    /** 附件:文件 **/
+    setFileName(fileName) {
+      this.form.fileName = fileName
+    },
+    removeFileName(index) {
+      this.form.fileName = ''
+      this.form.reportUrl = ''
+    },
     /** 查询部门下拉树结构 */
     getTreeSelect() {
       treeselectAll().then(response => {
@@ -282,6 +293,14 @@ export default {
       this.reset();
       const id = row.id || this.ids
       getReport(id).then(response => {
+        if (response.data.reportUrl !== "" && response.data.reportUrl != null) {
+          const list = response.data.reportUrl.split(',');
+          for (var a = 0; a < list.length; a++) {
+            let listurl = list[a].split('+')
+            console.log(listurl)
+            this.fileName = listurl[1]
+          }
+        }
         this.form = response.data;
         this.open = true;
         this.title = "修改维护报告";

+ 334 - 0
construction-ui/src/views/construction/riskregister/gasinspectionreformanalysis/index.vue

@@ -0,0 +1,334 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="燃气普及率" prop="gasPenetrationRate">
+        <el-input
+          v-model="queryParams.gasPenetrationRate"
+          placeholder="请输入燃气普及率"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="燃气改造率" prop="gasConversionRate">
+        <el-input
+          v-model="queryParams.gasConversionRate"
+          placeholder="请输入燃气改造率"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="统计日期" prop="statsPeriod">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.statsPeriod"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择统计日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="gasinspectionreformanalysisList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <!--                    <el-table-column label="主键ID" align="center" prop="id" />-->
+      <el-table-column label="燃气普及率" align="center" prop="gasPenetrationRate">
+        <template slot-scope="scope">
+          <span>{{ scope.row.gasPenetrationRate }}%</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="燃气改造率" align="center" prop="gasConversionRate">
+        <template slot-scope="scope">
+          <span>{{ scope.row.gasConversionRate }}%</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="统计日期" align="center" prop="statsPeriod" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.statsPeriod, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="燃气普及率环比变化值" align="center" prop="gasPenetrationMom">
+        <template slot-scope="scope">
+          <span>{{ scope.row.gasPenetrationMom }}%</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="燃气改造率环比变化值" align="center" prop="gasConversionMom">
+        <template slot-scope="scope">
+          <span>{{ scope.row.gasConversionMom }}%</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改燃气查改分析数据对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="燃气普及率" prop="gasPenetrationRate">
+          <el-input v-model="form.gasPenetrationRate" placeholder="请输入燃气普及率" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="燃气改造率" prop="gasConversionRate">
+          <el-input v-model="form.gasConversionRate" placeholder="请输入燃气改造率" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="统计日期" prop="statsPeriod">
+          <el-date-picker clearable size="small"
+                          v-model="form.statsPeriod"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择统计日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="燃气普及率环比变化值" prop="gasPenetrationMom">
+          <el-input v-model="form.gasPenetrationMom" placeholder="请输入燃气普及率环比变化值" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="燃气改造率环比变化值" prop="gasConversionMom">
+          <el-input v-model="form.gasConversionMom" placeholder="请输入燃气改造率环比变化值" style="width: 200px"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listGasinspectionreformanalysis,
+  getGasinspectionreformanalysis,
+  delGasinspectionreformanalysis,
+  addGasinspectionreformanalysis,
+  updateGasinspectionreformanalysis
+} from "@/api/construction/riskregister/gasinspectionreformanalysis";
+
+export default {
+  name: "Gasinspectionreformanalysis",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 燃气查改分析数据表格数据
+      gasinspectionreformanalysisList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        gasPenetrationRate: null,
+        gasConversionRate: null,
+        statsPeriod: null,
+        gasPenetrationMom: null,
+        gasConversionMom: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        gasPenetrationRate: [
+          {required: true, message: "燃气普及率不能为空", trigger: "blur"}
+        ],
+        gasConversionRate: [
+          {required: true, message: "燃气改造率不能为空", trigger: "blur"}
+        ],
+        statsPeriod: [
+          {required: true, message: "统计日期不能为空", trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询燃气查改分析数据列表 */
+    getList() {
+      this.loading = true;
+      listGasinspectionreformanalysis(this.queryParams).then(response => {
+        this.gasinspectionreformanalysisList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        gasPenetrationRate: null,
+        gasConversionRate: null,
+        statsPeriod: null,
+        gasPenetrationMom: null,
+        gasConversionMom: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加燃气查改分析数据";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getGasinspectionreformanalysis(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改燃气查改分析数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateGasinspectionreformanalysis(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addGasinspectionreformanalysis(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除燃气查改分析数据编号为"' + ids + '"的数据项?').then(function () {
+        return delGasinspectionreformanalysis(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/gasinspectionreformanalysis/export', {
+        ...this.queryParams
+      }, `gasinspectionreformanalysis_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 322 - 0
construction-ui/src/views/construction/riskregister/monitor/index.vue

@@ -0,0 +1,322 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="监测日期" prop="monitorPeriod">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.monitorPeriod"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择监测日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="管道类型" prop="pipelineType">
+        <el-select v-model="queryParams.pipelineType" placeholder="请选择管道类型" clearable size="small">
+          <el-option
+            v-for="dict in dict.type.lifeline_industry"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="monitorList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+<!--      <el-table-column label="主键ID" align="center" prop="id"/>-->
+      <el-table-column label="监测日期" align="center" prop="monitorPeriod" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.monitorPeriod, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="管道类型" align="center" prop="pipelineType">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.lifeline_industry" :value="scope.row.pipelineType"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="监测数值" align="center" prop="monitorValue"/>
+      <el-table-column label="环比变化值" align="center" prop="mom"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改管网智能化监测对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="监测日期" prop="monitorPeriod">
+          <el-date-picker clearable size="small"
+                          v-model="form.monitorPeriod"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择监测日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="管道类型" prop="pipelineType">
+          <el-select v-model="form.pipelineType" placeholder="请选择管道类型">
+            <el-option
+              v-for="dict in dict.type.lifeline_industry"
+              :key="dict.value"
+              :label="dict.label"
+              :value="parseInt(dict.value)"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="监测数值" prop="monitorValue">
+          <el-input v-model="form.monitorValue" placeholder="请输入监测数值" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="环比变化值" prop="mom">
+          <el-input v-model="form.mom" placeholder="请输入环比变化值" style="width: 200px"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {listMonitor, getMonitor, delMonitor, addMonitor, updateMonitor} from "@/api/construction/riskregister/monitor";
+
+export default {
+  name: "Monitor",
+  dicts: ['lifeline_industry'],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 管网智能化监测表格数据
+      monitorList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        monitorPeriod: null,
+        pipelineType: null,
+        monitorValue: null,
+        mom: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        monitorPeriod: [
+          {required: true, message: "监测日期不能为空", trigger: "blur"}
+        ],
+        pipelineType: [
+          {required: true, message: "管道类型不能为空", trigger: "change"}
+        ],
+        monitorValue: [
+          {required: true, validator: this.validateNumber, trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 自定义数值类型校验
+    validateNumber(rule, value, callback) {
+      if (value != null && value !== '') {
+        if (!/^[1-9]\d*$/.test(value)) {
+          callback(new Error('必须为正整数值'))
+        } else {
+          if (value && (value < 0 || value > 999999)) {
+            callback(new Error('必须在0到999999之间'));
+          } else {
+            callback();
+          }
+        }
+      } else {
+        callback(new Error('破损数量不能为空'));
+      }
+    },
+    /** 查询管网智能化监测列表 */
+    getList() {
+      this.loading = true;
+      listMonitor(this.queryParams).then(response => {
+        this.monitorList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        monitorPeriod: null,
+        pipelineType: null,
+        monitorValue: null,
+        mom: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加管网智能化监测";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getMonitor(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改管网智能化监测";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateMonitor(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addMonitor(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除管网智能化监测编号为"' + ids + '"的数据项?').then(function () {
+        return delMonitor(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/monitor/export', {
+        ...this.queryParams
+      }, `monitor_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 348 - 0
construction-ui/src/views/construction/riskregister/pipedamagestats/index.vue

@@ -0,0 +1,348 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="统计日期" prop="statsPeriod">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.statsPeriod"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择统计日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="归属行业" prop="pipeType">
+        <el-select v-model="queryParams.pipeType" placeholder="请选择归属行业" clearable size="small">
+          <el-option
+            v-for="dict in dict.type.lifeline_industry"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="破损数量" prop="damageCount">
+        <el-input
+          v-model="queryParams.damageCount"
+          placeholder="请输入破损数量"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="pipedamagestatsList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <!--                    <el-table-column label="主键ID" align="center" prop="id" />-->
+      <el-table-column label="统计日期" align="center" prop="statsPeriod" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.statsPeriod, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="归属行业" align="center" prop="pipeType">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.lifeline_industry" :value="scope.row.pipeType"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="破损数量" align="center" prop="damageCount"/>
+      <el-table-column label="环比变化值" align="center" prop="mom" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改管道破损统计数据对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="统计日期" prop="statsPeriod">
+          <el-date-picker clearable size="small"
+                          v-model="form.statsPeriod"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择统计日期"
+                          :picker-options="pickerOptions">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="归属行业" prop="pipeType">
+          <el-select v-model="form.pipeType" placeholder="请选择归属行业">
+            <el-option
+              v-for="dict in dict.type.lifeline_industry"
+              :key="dict.value"
+              :label="dict.label"
+              :value="parseInt(dict.value)"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="破损数量" prop="damageCount">
+          <el-input v-model="form.damageCount" placeholder="请输入破损数量" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="环比变化值" prop="mom">
+          <el-input v-model="form.mom" placeholder="请输入破损数量" style="width: 200px"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listPipedamagestats,
+  getPipedamagestats,
+  delPipedamagestats,
+  addPipedamagestats,
+  updatePipedamagestats
+} from "@/api/construction/riskregister/pipedamagestats";
+
+export default {
+  name: "Pipedamagestats",
+  dicts: ['lifeline_industry'],
+  data() {
+    return {
+      pickerOptions: {
+        disabledDate(time) {
+          return time.getTime() > Date.now();
+        }
+      },
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 管道破损统计数据表格数据
+      pipedamagestatsList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        statsPeriod: null,
+        pipeType: null,
+        damageCount: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        statsPeriod: [
+          {required: true, message: "统计日期不能为空", trigger: "blur"}
+        ],
+        pipeType: [
+          {required: true, message: "归属行业不能为空", trigger: "change"}
+        ],
+        damageCount: [
+          {required: true, validator: this.validateNumber, trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 自定义数值类型校验
+    validateNumber(rule, value, callback) {
+      if (value != null && value !== '') {
+        if (!/^[1-9]\d*$/.test(value)) {
+          callback(new Error('必须为正整数值'))
+        } else {
+          if (value && (value < 0 || value > 999999)) {
+            callback(new Error('必须在0到999999之间'));
+          } else {
+            callback();
+          }
+        }
+      } else {
+        callback(new Error('破损数量不能为空'));
+      }
+    },
+    /** 查询管道破损统计数据列表 */
+    getList() {
+      this.loading = true;
+      listPipedamagestats(this.queryParams).then(response => {
+        this.pipedamagestatsList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      const today = new Date();
+      const yyyy = today.getFullYear();
+      const mm = String(today.getMonth() + 1).padStart(2, '0');
+      const dd = String(today.getDate()).padStart(2, '0');
+      const currentDate = `${yyyy}-${mm}-${dd}`;
+
+      this.form = {
+        id: null,
+        statsPeriod: currentDate,
+        pipeType: null,
+        damageCount: null,
+        mom: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加管道破损统计数据";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getPipedamagestats(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改管道破损统计数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updatePipedamagestats(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addPipedamagestats(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除管道破损统计数据编号为"' + ids + '"的数据项?').then(function () {
+        return delPipedamagestats(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/pipedamagestats/export', {
+        ...this.queryParams
+      }, `pipedamagestats_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 323 - 0
construction-ui/src/views/construction/riskregister/satisfaction/index.vue

@@ -0,0 +1,323 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="调查日期" prop="surveyPeriod">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.surveyPeriod"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择调查日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="满意度等级" prop="satisfactionLevel">
+        <el-select v-model="queryParams.satisfactionLevel" placeholder="请选择满意度等级" clearable size="small">
+          <el-option
+            v-for="dict in dict.type.satisfaction_level"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="satisfactionList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+<!--      <el-table-column label="主键ID" align="center" prop="id"/>-->
+      <el-table-column label="调查日期" align="center" prop="surveyPeriod" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.surveyPeriod, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="满意度等级" align="center" prop="satisfactionLevel">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.satisfaction_level" :value="scope.row.satisfactionLevel"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="调查人数" align="center" prop="satisfactionCount"/>
+      <el-table-column label="调查人数的百分比" align="center" prop="percentage"/>
+      <el-table-column label="环比变化率" align="center" prop="qoqChange"/>
+      <el-table-column label="本周期总调查人数" align="center" prop="totalRespondents"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改危旧桥梁满意度调查数据对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="180px">
+        <el-form-item label="调查日期" prop="surveyPeriod">
+          <el-date-picker clearable size="small"
+                          v-model="form.surveyPeriod"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择调查日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="满意度等级" prop="satisfactionLevel">
+          <el-select v-model="form.satisfactionLevel" placeholder="请选择满意度等级">
+            <el-option
+              v-for="dict in dict.type.satisfaction_level"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="调查人数" prop="satisfactionCount">
+          <el-input v-model="form.satisfactionCount" placeholder="请输入调查人数" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="调查人数的百分比" prop="percentage">
+          <el-input v-model="form.percentage" placeholder="请输入调查人数的百分比" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="环比变化率" prop="qoqChange">
+          <el-input v-model="form.qoqChange" placeholder="请输入环比变化率" style="width: 200px"/>
+        </el-form-item>
+        <el-form-item label="本周期总调查人数" prop="totalRespondents">
+          <el-input v-model="form.totalRespondents" placeholder="请输入本周期总调查人数" style="width: 200px"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listSatisfaction,
+  getSatisfaction,
+  delSatisfaction,
+  addSatisfaction,
+  updateSatisfaction
+} from "@/api/construction/riskregister/satisfaction";
+
+export default {
+  name: "Satisfaction",
+  dicts: ['satisfaction_level'],
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 危旧桥梁满意度调查数据表格数据
+      satisfactionList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        surveyPeriod: null,
+        satisfactionLevel: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        surveyPeriod: [
+          {required: true, message: "调查日期不能为空", trigger: "blur"}
+        ],
+        satisfactionLevel: [
+          {required: true, message: "满意度等级不能为空", trigger: "change"}
+        ],
+        satisfactionCount: [
+          {required: true, message: "调查人数不能为空", trigger: "blur"}
+        ],
+        percentage: [
+          {required: true, message: "调查人数的百分比不能为空", trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询危旧桥梁满意度调查数据列表 */
+    getList() {
+      this.loading = true;
+      listSatisfaction(this.queryParams).then(response => {
+        this.satisfactionList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        surveyPeriod: null,
+        satisfactionLevel: null,
+        satisfactionCount: null,
+        percentage: null,
+        qoqChange: null,
+        totalRespondents: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加危旧桥梁满意度调查数据";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getSatisfaction(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改危旧桥梁满意度调查数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateSatisfaction(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addSatisfaction(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除危旧桥梁满意度调查数据编号为"' + ids + '"的数据项?').then(function () {
+        return delSatisfaction(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/satisfaction/export', {
+        ...this.queryParams
+      }, `satisfaction_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 302 - 0
construction-ui/src/views/construction/riskregister/smartcoveragerate/index.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="统计日期" prop="statisticsDate">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.statisticsDate"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择统计日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="smartcoveragerateList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+<!--      <el-table-column label="主键ID" align="center" prop="id"/>-->
+      <el-table-column label="排水管网普查覆盖率" align="center" prop="drainagePipelineSurveyRate"/>
+      <el-table-column label="供热管网普查覆盖率" align="center" prop="heatingPipelineSurveyRate"/>
+      <el-table-column label="城市生活污水集中收集率" align="center" prop="urbanSewageCollectionRate"/>
+      <el-table-column label="应急供水保障率" align="center" prop="emergencyWaterSupplyRate"/>
+      <el-table-column label="统计日期" align="center" prop="statisticsDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.statisticsDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改普查覆盖率对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="240px">
+        <el-form-item label="排水管网普查覆盖率" prop="drainagePipelineSurveyRate">
+          <el-input v-model="form.drainagePipelineSurveyRate" placeholder="请输入排水管网普查覆盖率" style="width: 400px"/>
+        </el-form-item>
+        <el-form-item label="供热管网普查覆盖率" prop="heatingPipelineSurveyRate">
+          <el-input v-model="form.heatingPipelineSurveyRate" placeholder="请输入供热管网普查覆盖率" style="width: 400px"/>
+        </el-form-item>
+        <el-form-item label="城市生活污水集中收集率" prop="urbanSewageCollectionRate">
+          <el-input v-model="form.urbanSewageCollectionRate" placeholder="请输入城市生活污水集中收集率" style="width: 400px"/>
+        </el-form-item>
+        <el-form-item label="应急供水保障率" prop="emergencyWaterSupplyRate">
+          <el-input v-model="form.emergencyWaterSupplyRate" placeholder="请输入应急供水保障率" style="width: 400px"/>
+        </el-form-item>
+        <el-form-item label="统计日期" prop="statisticsDate">
+          <el-date-picker clearable size="small"
+                          v-model="form.statisticsDate"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择统计日期">
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listSmartcoveragerate,
+  getSmartcoveragerate,
+  delSmartcoveragerate,
+  addSmartcoveragerate,
+  updateSmartcoveragerate
+} from "@/api/construction/riskregister/smartcoveragerate";
+
+export default {
+  name: "Smartcoveragerate",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 普查覆盖率表格数据
+      smartcoveragerateList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        drainagePipelineSurveyRate: null,
+        heatingPipelineSurveyRate: null,
+        urbanSewageCollectionRate: null,
+        emergencyWaterSupplyRate: null,
+        statisticsDate: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        drainagePipelineSurveyRate: [
+          {required: true, message: "排水管网普查覆盖率不能为空", trigger: "blur"}
+        ],
+        heatingPipelineSurveyRate: [
+          {required: true, message: "供热管网普查覆盖率不能为空", trigger: "blur"}
+        ],
+        urbanSewageCollectionRate: [
+          {required: true, message: "城市生活污水集中收集率不能为空", trigger: "blur"}
+        ],
+        emergencyWaterSupplyRate: [
+          {required: true, message: "应急供水保障率不能为空", trigger: "blur"}
+        ],
+        statisticsDate: [
+          {required: true, message: "统计日期不能为空", trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询普查覆盖率列表 */
+    getList() {
+      this.loading = true;
+      listSmartcoveragerate(this.queryParams).then(response => {
+        this.smartcoveragerateList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        drainagePipelineSurveyRate: null,
+        heatingPipelineSurveyRate: null,
+        urbanSewageCollectionRate: null,
+        emergencyWaterSupplyRate: null,
+        statisticsDate: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加普查覆盖率";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getSmartcoveragerate(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改普查覆盖率";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateSmartcoveragerate(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addSmartcoveragerate(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除普查覆盖率编号为"' + ids + '"的数据项?').then(function () {
+        return delSmartcoveragerate(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/smartcoveragerate/export', {
+        ...this.queryParams
+      }, `smartcoveragerate_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 286 - 0
construction-ui/src/views/construction/riskregister/wateranalysis/index.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="统计日期" prop="periodDate">
+        <el-date-picker clearable size="small"
+                        v-model="queryParams.periodDate"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择统计日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="居民用水量" prop="waterUsage">
+        <el-input
+          v-model="queryParams.waterUsage"
+          placeholder="请输入居民用水量"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="wateranalysisList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+<!--      <el-table-column label="主键ID" align="center" prop="id"/>-->
+      <el-table-column label="统计日期" align="center" prop="periodDate" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.periodDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="居民用水量" align="center" prop="waterUsage"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['riskregister:wateranalysis:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['riskregister:wateranalysis:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改居民用水分析数据对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="统计日期" prop="periodDate">
+          <el-date-picker clearable size="small"
+                          v-model="form.periodDate"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择统计日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="居民用水量" prop="waterUsage">
+          <el-input v-model="form.waterUsage" placeholder="请输入居民用水量" style="width: 200px"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listWateranalysis,
+  getWateranalysis,
+  delWateranalysis,
+  addWateranalysis,
+  updateWateranalysis
+} from "@/api/construction/riskregister/wateranalysis";
+
+export default {
+  name: "Wateranalysis",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 居民用水分析数据表格数据
+      wateranalysisList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        periodDate: null,
+        waterUsage: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        periodDate: [
+          {required: true, message: "统计日期不能为空", trigger: "blur"}
+        ],
+        waterUsage: [
+          {required: true, message: "居民用水量不能为空", trigger: "blur"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询居民用水分析数据列表 */
+    getList() {
+      this.loading = true;
+      listWateranalysis(this.queryParams).then(response => {
+        this.wateranalysisList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        periodDate: null,
+        waterUsage: null,
+        createTime: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加居民用水分析数据";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getWateranalysis(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改居民用水分析数据";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateWateranalysis(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addWateranalysis(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除居民用水分析数据编号为"' + ids + '"的数据项?').then(function () {
+        return delWateranalysis(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('riskregister/wateranalysis/export', {
+        ...this.queryParams
+      }, `wateranalysis_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 532 - 0
construction-ui/src/views/construction/supervision/index.vue

@@ -0,0 +1,532 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"
+             @submit.prevent.native>
+      <el-form-item label="工地名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入工地名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['supervision:supervision:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['supervision:supervision:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['supervision:supervision:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['supervision:supervision:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="supervisionList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="工地名称" align="center" prop="name"/>
+      <el-table-column label="所属行业" align="center" prop="type">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.lifeline_industry" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="负责人" align="center" prop="principal"/>
+      <el-table-column label="联系电话" align="center" prop="phone"/>
+      <el-table-column label="施工状态" align="center" prop="construction">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.construction_status" :value="scope.row.construction"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="开始时间" align="center" prop="startTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束时间" align="center" prop="endTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="质量监管" align="center" prop="quality"/>
+      <el-table-column label="安全监管" align="center" prop="security"/>
+      <el-table-column label="部门名称" align="center" prop="deptName"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['supervision:supervision:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['supervision:supervision:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改工地监管对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="1000px" class="form-style">
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="工地名称" prop="name">
+              <el-input v-model="form.name" placeholder="请输入工地名称" maxlength="20" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="所属行业" prop="type">
+              <el-select v-model="form.type" clearable placeholder="请选择所属行业">
+                <el-option
+                  v-for="dict in dict.type.lifeline_industry"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="负责人" prop="principal">
+              <el-input v-model="form.principal" placeholder="请输入负责人" maxlength="20"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="联系电话" prop="phone">
+              <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="13"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="经度" prop="longitude" @dblclick.native="showMap">
+              <el-input v-model="form.longitude" placeholder="鼠标双击选择经纬度" maxlength="32"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="纬度" prop="latitude" @dblclick.native="showMap">
+              <el-input v-model="form.latitude" placeholder="鼠标双击选择经纬度" maxlength="32"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="开始时间" prop="startTime">
+              <el-date-picker clearable size="small"
+                              v-model="form.startTime"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="选择开始时间">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="结束时间" prop="endTime">
+              <el-date-picker clearable size="small"
+                              v-model="form.endTime"
+                              type="date"
+                              value-format="yyyy-MM-dd"
+                              placeholder="选择结束时间">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="施工状态" prop="construction">
+              <el-select v-model="form.construction" clearable placeholder="请选择施工状态">
+                <el-option
+                  v-for="dict in dict.type.construction_status"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="质量监管" prop="quality">
+              <el-input v-model="form.quality" placeholder="请输入质量监管" maxlength="20"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="安全监管" prop="security">
+              <el-input v-model="form.security" placeholder="请输入安全监管" maxlength="20"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="说明" prop="describe">
+              <el-input v-model="form.describe" placeholder="请输入说明" maxlength="50"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="绑定设备" prop="deviceList">
+              <el-select v-model="form.deviceList" filterable placeholder="请选择设备" multiple>
+                <el-option
+                  v-for="dict in cameraList"
+                  :key="dict.id"
+                  :label="dict.cameraName"
+                  :value="dict.id"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="所属公司" prop="deptId">
+              <treeselect v-model="form.deptId" :noOptionsText="'空'" :noResultsText="'空'"
+                          :options="deptOptions"
+                          :show-count="true" multiple:false placeholder="请选择公司" @select="hx"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="图片" prop="attachPaths">
+              <DataImageUpload ref="ImageUpload" :fileType="['png', 'jpg', 'jpeg']" :value="form.attachPaths"
+                               @input="getUrl"></DataImageUpload>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <ISuperMap v-if="ISuperMapvisible" ref="ISuperMap" @send="send"/>
+  </div>
+</template>
+
+<script>
+import {
+  addSupervision,
+  delSupervision,
+  getSupervision,
+  listSupervision,
+  updateSupervision,
+  selectCenterMonitorlList
+} from "@/api/construction/supervision/supervision";
+import Treeselect from "@riophae/vue-treeselect";
+import {treeselectAll} from "@/api/system/dept";
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import ISuperMap from "@/views/construction/common/ISuperMap.vue";
+import {checkLat, checkLon, validPhoneMobile} from "@/api/system/rules";
+import DataImageUpload from "@/components/ImageUpload/dataUpload.vue";
+
+export default {
+  dicts: ['construction_status','lifeline_industry'],
+  name: "Supervision",
+  components: {ISuperMap, Treeselect,DataImageUpload},
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 工地监管表格数据
+      supervisionList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 部门树选项
+      deptOptions: undefined,
+      sign: 1,
+      ISuperMapvisible: false,
+      cameraList: [],//设备集合
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: null,
+        type: null,
+        principal: null,
+        phone: null,
+        construction: null,
+        startTime: null,
+        endTime: null,
+        quality: null,
+        security: null,
+        longitude: null,
+        latitude: null,
+        describe: null,
+        createName: null,
+        updateName: null,
+        deptId: null,
+        deptName: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name: [
+          {required: true, message: '工地名称不能为空', trigger: 'blur'}
+        ],
+        type: [
+          {required: true, message: '所属行业不能为空', trigger: 'blur'}
+        ],
+        deptId: [
+          {required: true, message: '所属公司不能为空', trigger: 'blur'}
+        ],
+        construction: [
+          {required: true, message: '施工状态不能为空', trigger: 'blur'}
+        ],
+        principal: [
+          {required: true, message: '负责人不能为空', trigger: 'blur'}
+        ],
+        startTime: [
+          {required: true, message: '开始时间不能为空', trigger: 'blur'}
+        ],
+        endTime: [
+          {required: true, message: '结束时间不能为空', trigger: 'blur'}
+        ],
+        phone: [
+          {required: true, message: '联系电话不能为空', trigger: 'blur'},
+          {validator: validPhoneMobile, trigger: 'blur'}
+        ],
+        longitude: [
+          {required: true, message: '经度不能为空', trigger: 'blur'},
+          {validator: checkLon, trigger: 'blur'}
+        ],
+        latitude: [
+          {required: true, message: '纬度不能为空', trigger: 'blur'},
+          {validator: checkLat, trigger: 'blur'}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getTreeSelect();
+    this.getMonitorList();
+  },
+  methods: {
+    /** 查询工地监管列表 */
+    getList() {
+      this.loading = true;
+      listSupervision(this.queryParams).then(response => {
+        this.supervisionList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    //查询摄像头列表
+    getMonitorList() {
+      selectCenterMonitorlList(this.queryParams).then(response => {
+        this.cameraList = response.data;
+      });
+    },
+    /** 查询部门下拉树结构 */
+    getTreeSelect() {
+      treeselectAll().then(response => {
+        this.deptOptions = response.data;
+      });
+    },
+    hx(node) {
+      this.form.dataDeptId = node.id
+      this.form.deptId = node.id
+      this.form.deptName = node.label
+      this.$refs.form.validateField("deptId")
+    },
+    showMap() {
+      this.ISuperMapvisible = true;
+      this.$nextTick(() => {
+        this.$refs.ISuperMap.init(this.sign, {
+          id: this.form.id,
+          longitude: this.form.longitude,
+          latitude: this.form.latitude,
+        })
+      })
+    },
+    send(val) {
+      if (val === true) {
+        this.ISuperMapvisible = false;
+        return;
+      }
+      if (this.sign === 1) {
+        this.form.longitude = val.longitude;
+        this.form.latitude = val.latitude;
+      }
+      this.ISuperMapvisible = false
+    },
+    getUrl(url) {
+      this.form.attachPaths = url
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        name: null,
+        type: null,
+        principal: null,
+        phone: null,
+        construction: null,
+        startTime: null,
+        endTime: null,
+        quality: null,
+        security: null,
+        longitude: null,
+        latitude: null,
+        describe: null,
+        createBy: null,
+        createName: null,
+        createTime: null,
+        updateBy: null,
+        updateName: null,
+        updateTime: null,
+        deptId: null,
+        deptName: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加工地监管";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getSupervision(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改工地监管";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateSupervision(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addSupervision(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除选中的数据项?').then(function () {
+        return delSupervision(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('sooka-digital-construction/supervision/export', {
+        ...this.queryParams
+      }, `工地管理_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 364 - 0
construction-ui/src/views/construction/supervision/log/index.vue

@@ -0,0 +1,364 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" @submit.prevent.native>
+      <el-form-item label="工地名称" prop="constructionName">
+        <el-input
+          v-model="queryParams.constructionName"
+          placeholder="请输入工地名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['constructionLog:log:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['constructionLog:log:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['constructionLog:log:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['constructionLog:log:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="logList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="工地名称" align="center" prop="constructionName"/>
+      <el-table-column label="施工状态" align="center" prop="construction">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.construction_status" :value="scope.row.construction"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="监管人" align="center" prop="supervisor"/>
+      <el-table-column label="监管人电话" align="center" prop="supervisorPhone"/>
+      <el-table-column label="监管类型" align="center" prop="supervisionType"/>
+      <el-table-column label="监管日期" align="center" prop="supervisionTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.supervisionTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="监管结果" align="center" prop="supervisionResult"/>
+      <el-table-column label="描述" align="center" prop="description"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['constructionLog:log:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['constructionLog:log:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改监管日志对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="800px" class="form-style">
+      <el-form ref="form" :model="form" :rules="rules" label-width="82px">
+        <el-form-item label="工地名称" prop="constructionId">
+          <el-select v-model="form.constructionId" filterable placeholder="请选择工地">
+            <el-option
+              v-for="dict in supervisionList"
+              :key="dict.id"
+              :label="dict.name"
+              :value="dict.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="施工状态" prop="construction">
+          <el-select v-model="form.construction" clearable placeholder="请选择施工状态">
+            <el-option
+              v-for="dict in dict.type.construction_status"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="监管人" prop="supervisor">
+          <el-input v-model="form.supervisor" placeholder="请输入监管人" maxlength="10"/>
+        </el-form-item>
+        <el-form-item label="监管人电话" prop="supervisorPhone">
+          <el-input v-model="form.supervisorPhone" placeholder="请输入监管人电话" maxlength="13"/>
+        </el-form-item>
+        <el-form-item label="监管类型" prop="supervisionType">
+          <el-input v-model="form.supervisionType" placeholder="请输入监管类型" maxlength="32"/>
+        </el-form-item>
+        <el-form-item label="监管日期" prop="supervisionTime">
+          <el-date-picker clearable size="small"
+                          v-model="form.supervisionTime"
+                          type="date"
+                          value-format="yyyy-MM-dd"
+                          placeholder="选择监管日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="监管结果" prop="supervisionResult">
+          <el-input v-model="form.supervisionResult" placeholder="请输入监管结果" maxlength="32"/>
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="form.description" placeholder="请输入描述" maxlength="50"/>
+        </el-form-item>
+        <el-form-item label="图片" prop="attachPaths">
+          <DataImageUpload ref="ImageUpload" :fileType="['png', 'jpg', 'jpeg']" :value="form.attachPaths"
+                           @input="getUrl"></DataImageUpload>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listSupervision,
+} from "@/api/construction/supervision/supervision";
+import {addLog, delLog, getLog, listLog, updateLog} from "@/api/construction/supervision/log";
+import DataImageUpload from "@/components/ImageUpload/dataUpload.vue";
+import {validPhoneMobile} from "@/api/system/rules";
+
+export default {
+  components: {DataImageUpload},
+  dicts: ['construction_status'],
+  name: "Log",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 监管日志表格数据
+      logList: [],
+      //工地列表
+      supervisionList:[],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        constructionId: null,
+        supervisor: null,
+        supervisorPhone: null,
+        supervisionType: null,
+        supervisionTime: null,
+        supervisionResult: null,
+        description: null,
+        construction: null,
+        createName: null,
+        updateName: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        constructionId: [
+          {required: true, message: '工地名称不能为空', trigger: 'blur'}
+        ],
+        construction: [
+          {required: true, message: '施工状态不能为空', trigger: 'blur'}
+        ],
+        supervisorPhone: [
+          {validator: validPhoneMobile, trigger: 'blur'}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.listSupervision();
+  },
+  methods: {
+    /** 查询工地监管列表 */
+    listSupervision() {
+      listSupervision().then(response => {
+        this.supervisionList = response.rows;
+      });
+    },
+    /** 查询监管日志列表 */
+    getList() {
+      this.loading = true;
+      listLog(this.queryParams).then(response => {
+        this.logList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    getUrl(url) {
+      this.form.attachPaths = url
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        constructionId: null,
+        supervisor: null,
+        supervisorPhone: null,
+        supervisionType: null,
+        supervisionTime: null,
+        supervisionResult: null,
+        description: null,
+        construction: null,
+        createBy: null,
+        createName: null,
+        createTime: null,
+        updateBy: null,
+        updateName: null,
+        updateTime: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加监管日志";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getLog(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改监管日志";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.form.constructionName = this.supervisionList.filter((item) => {
+        return this.form.constructionId == item.id;
+      })[0].name;
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateLog(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addLog(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$modal.confirm('是否确认删除监管日志编号为"' + ids + '"的数据项?').then(function () {
+        return delLog(ids);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('sooka-digital-construction/log/export', {
+        ...this.queryParams
+      }, `监管日志_${new Date().getTime()}.xlsx`)
+    }
+  }
+};
+</script>

+ 4 - 4
construction-ui/src/views/construction/utilityTunnel/pipe/index.vue

@@ -13,7 +13,7 @@
       <el-form-item label="管线类别" prop="pipeCategory">
         <el-select v-model="queryParams.pipeCategory" clearable placeholder="请选择管线类别" size="small">
           <el-option
-            v-for="dict in dict.type.gas_pipeline_category"
+            v-for="dict in dict.type.ut_pipeline_category"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -68,7 +68,7 @@
       <el-table-column align="center" label="管线编码" prop="pipeCode"/>
       <el-table-column align="center" label="管线类别" prop="pipeCategory">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.gas_pipeline_category" :value="scope.row.pipeCategory"/>
+          <dict-tag :options="dict.type.ut_pipeline_category" :value="scope.row.pipeCategory"/>
         </template>
       </el-table-column>
       <el-table-column align="center" label="地市编码" prop="cityCode"/>
@@ -135,7 +135,7 @@
             <el-form-item label="管线类别" prop="pipeCategory">
               <el-select v-model="form.pipeCategory" placeholder="请选择管线类别">
                 <el-option
-                  v-for="dict in dict.type.gas_pipeline_category"
+                  v-for="dict in dict.type.ut_pipeline_category"
                   :key="dict.value"
                   :label="dict.label"
                   :value="dict.value"
@@ -273,7 +273,7 @@ import {addPipe, delPipe, getPipe, listPipe, updatePipe} from "@/api/constructio
 
 export default {
   name: "Pipe",
-  dicts: ['gas_pipeline_category'],
+  dicts: ['ut_pipeline_category'],
   data() {
     return {
       // 遮罩层

+ 6 - 0
package-lock.json

@@ -0,0 +1,6 @@
+{
+  "name": "sooka-digital-construction",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {}
+}

+ 251 - 0
src/main/java/com/sooka/sponest/construction/api/PlatformBridge.java

@@ -0,0 +1,251 @@
+package com.sooka.sponest.construction.api;
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.sooka.sponest.construction.api.vo.*;
+import com.sooka.sponest.construction.bridge.domain.BridgeAllyCrossPier;
+import com.sooka.sponest.construction.bridge.service.IBridgeAllyCrossPierService;
+import com.sooka.sponest.construction.bridge.service.IBridgeCheckDiseaseService;
+import com.sooka.sponest.construction.bridge.service.IBridgeInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/platformBridge")
+public class PlatformBridge extends BaseController {
+
+    @Autowired
+    private IBridgeAllyCrossPierService bridgeAllyCrossPierService;
+
+    @Autowired
+    private IBridgeCheckDiseaseService bridgeCheckDiseaseService;
+
+    @Autowired
+    private IBridgeInfoService bridgeInfoService;
+
+    /**
+     * 桥梁信息展示联、跨、墩文本信息
+     * @return
+     */
+    @GetMapping("/getBridgeAllyCrossPier")
+    public TableDataInfo getBridgeSpanPierInfo() {
+        return getDataTable(this.bridgeAllyCrossPierService.selectBridgeAllyCrossPierList(new BridgeAllyCrossPier()));
+    }
+
+    /**
+     * 根据桥墩型式统计各区划墩数量(原始数据格式)
+     * @return
+     */
+    @GetMapping("/getDistrictPierCountByType")
+    public TableDataInfo getDistrictPierCountByType() {
+        List<DistrictPierCountByTypeVO> result = this.bridgeAllyCrossPierService.getDistrictPierCountByType();
+        return getDataTable(result);
+    }
+
+    /**
+     * 根据桥墩型式统计各区划墩数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getDistrictPierCountChart")
+    public AjaxResult getDistrictPierCountChart() {
+        List<DistrictPierCountByTypeVO> dataList = this.bridgeAllyCrossPierService.getDistrictPierCountByType();
+        // 获取所有唯一的桥墩型式(xdata)
+        List<String> pierTypes = dataList.stream()
+                .map(DistrictPierCountByTypeVO::getDivName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 获取所有唯一的区划名称
+        List<String> xdata = dataList.stream()
+                .map(DistrictPierCountByTypeVO::getPierType)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 构建ydata:按区划分组,每个区划包含各桥墩型式的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = pierTypes.stream()
+                .map(divName -> {
+                    // 为每个桥墩型式填充该区划的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(pierType -> dataList.stream()
+                                    .filter(item -> divName.equals(item.getDivName()) && pierType.equals(item.getPierType()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getPierCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(divName, values);
+                })
+                .collect(Collectors.toList());
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据区划统计跨信息长度
+     * @return
+     */
+    @GetMapping("/getCrossLenByRegion")
+    public TableDataInfo getCrossLenByRegion() {
+        List<CrossLenByRegionVO> result = this.bridgeAllyCrossPierService.getCrossLenByRegion();
+        return getDataTable(result);
+    }
+
+    /**
+     * 根据缺损类型统计缺损范围数量
+     * @return
+     */
+    @GetMapping("/getDefectScopeCountByType")
+    public TableDataInfo getDefectScopeCountByType() {
+        List<DefectScopeCountByTypeVO> result = this.bridgeCheckDiseaseService.getDefectScopeCountByType();
+        return getDataTable(result);
+    }
+
+    /**
+     * 根据区划统计缺损类型数量
+     * @return
+     */
+    @GetMapping("/getDistrictDefectTypeCount")
+    public AjaxResult getDistrictDefectTypeCount() {
+        List<DistrictDefectTypeCountVO> dataList = this.bridgeCheckDiseaseService.getDistrictDefectTypeCount();
+        // 获取所有唯一的缺陷类型(xdata)
+        List<String> defectTypes = dataList.stream()
+                .map(DistrictDefectTypeCountVO::getDivName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 获取所有唯一的区划名称
+        List<String> xdata = dataList.stream()
+                .map(DistrictDefectTypeCountVO::getDefectTypeName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 构建ydata:按区划分组,每个包含缺陷类型的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = defectTypes.stream()
+                .map(divName -> {
+                    // 为每个缺陷类型填充该区划的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(defectType -> dataList.stream()
+                                    .filter(item -> divName.equals(item.getDivName()) && defectType.equals(item.getDefectTypeName()))
+                                    .findFirst()
+                                    .map(DistrictDefectTypeCountVO::getDefectCount)
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(divName, values);
+                })
+                .collect(Collectors.toList());
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据建设年代统计桥梁总长度
+     * @return
+     */
+    @GetMapping("/getConstructionYearBridgeTotalLength")
+    public TableDataInfo getConstructionYearBridgeTotalLength() {
+        return getDataTable(this.bridgeInfoService.getConstructionYearBridgeTotalLength());
+    }
+
+    /**
+     * 根据建设年代统计结构类型数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getConstructionYearStructureCount")
+    public AjaxResult getConstructionYearStructureCount() {
+        List<ConstructionYearStructureCountVO> dataList = this.bridgeInfoService.getConstructionYearStructureCount();
+
+        // 获取所有唯一的建设年代(xdata)
+        List<String> xdata = dataList.stream()
+                .map(ConstructionYearStructureCountVO::getConstructionYear)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的结构类型
+        List<String> structureTypes = dataList.stream()
+                .map(ConstructionYearStructureCountVO::getStructureType)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按结构类型分组,每个类型包含在各建设年代的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = structureTypes.stream()
+                .map(structureType -> {
+                    // 为每个建设年代填充该结构类型的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(constructionYear -> dataList.stream()
+                                    .filter(item -> constructionYear.equals(item.getConstructionYear()) 
+                                            && structureType.equals(item.getStructureType()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getUseCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+
+                    return new EChartsBarLineChartVO.SeriesData(structureType, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据桥梁架构统计桥梁总长度
+     * @return
+     */
+    @GetMapping("/getStructureTypeBridgeTotalLength")
+    public TableDataInfo getStructureTypeBridgeTotalLength() {
+        return getDataTable(this.bridgeInfoService.getStructureTypeBridgeTotalLength());
+    }
+
+    /**
+     * 根据区划统计桥梁结构(图表格式)
+     * @return
+     */
+    @GetMapping("/getDistrictStructureCount")
+    public AjaxResult getDistrictStructureCount() {
+        List<DistrictStructureCountVO> dataList = this.bridgeInfoService.getDistrictStructureCount();
+
+        // 获取所有唯一的结构类型(xdata)
+        List<String> xdata = dataList.stream()
+                .map(DistrictStructureCountVO::getStructureType)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的区划名称
+        List<String> districts = dataList.stream()
+                .map(DistrictStructureCountVO::getDivName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按区划分组,每个区划包含在各结构类型的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = districts.stream()
+                .map(district -> {
+                    // 为每个结构类型填充该区划的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(structureType -> dataList.stream()
+                                    .filter(item -> structureType.equals(item.getStructureType()) 
+                                            && district.equals(item.getDivName()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getStructureCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+
+                    return new EChartsBarLineChartVO.SeriesData(district, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+}

+ 463 - 85
src/main/java/com/sooka/sponest/construction/api/PlatformDeviceApi.java

@@ -5,6 +5,7 @@ import com.ruoyi.common.core.web.controller.BaseController;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.TableDataInfo;
 import com.ruoyi.common.security.utils.DictUtils;
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceListVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
@@ -12,6 +13,9 @@ import com.sooka.sponest.construction.bridge.domain.BridgeDevice;
 import com.sooka.sponest.construction.bridge.service.IBridgeDeviceService;
 import com.sooka.sponest.construction.drainage.domain.DrainageDeviceBaseInfoData;
 import com.sooka.sponest.construction.drainage.service.IDrainageDeviceBaseInfoDataService;
+import com.sooka.sponest.construction.event.domain.BO.EventSubjectBO;
+import com.sooka.sponest.construction.event.domain.VO.EventSubjectQueryVO;
+import com.sooka.sponest.construction.event.service.EventSubjectService;
 import com.sooka.sponest.construction.gas.domain.GasDeviceBaseInfoData;
 import com.sooka.sponest.construction.gas.service.IGasDeviceBaseInfoDataService;
 import com.sooka.sponest.construction.heating.domain.HeatingDevice;
@@ -22,11 +26,14 @@ import com.sooka.sponest.construction.waterSupply.domain.WaterSupplyDeviceBaseIn
 import com.sooka.sponest.construction.waterSupply.service.IWaterSupplyDeviceBaseInfoService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.function.BiFunction;
 
 @Slf4j
 @RestController
@@ -51,6 +58,9 @@ public class PlatformDeviceApi extends BaseController {
     @Autowired
     private IUtilityTunnelDeviceService utilityTunnelDeviceService;
 
+    @Autowired
+    private EventSubjectService eventSubjectService;
+
     /**
      * 设备汇总接口
      */
@@ -58,6 +68,15 @@ public class PlatformDeviceApi extends BaseController {
     public AjaxResult getDeviceSummary(@RequestParam(value = "industry", required = true) int industry) {
         List<Map<String, Object>> list = new ArrayList<>();
 
+        // 行业名称映射
+        Map<Integer, String> industryNameMap = new HashMap<>();
+        industryNameMap.put(1, "燃气");
+        industryNameMap.put(2, "排水");
+        industryNameMap.put(3, "供热");
+        industryNameMap.put(4, "桥梁");
+        industryNameMap.put(5, "供水");
+        industryNameMap.put(6, "管廊");
+
         Map<Integer, Supplier<List<DeviceSummaryVO>>> serviceMap = new HashMap<>();
         serviceMap.put(1, () -> this.gasDeviceBaseInfoDataService.getDeviceSummary());
         serviceMap.put(2, () -> this.drainageDeviceBaseInfoDataService.getDeviceSummary());
@@ -68,8 +87,16 @@ public class PlatformDeviceApi extends BaseController {
 
         try {
             if (serviceMap.containsKey(industry)) {
+                // 查询指定行业的真实数据
                 List<DeviceSummaryVO> tempList = serviceMap.get(industry).get();
                 deviceSummaryVO2List(tempList, list);
+                // 为其他行业添加零值数据
+                for (Map.Entry<Integer, String> entry : industryNameMap.entrySet()) {
+                    if (!entry.getKey().equals(industry)) {
+                        Map<String, Object> zeroMap = createZeroDeviceSummary(entry.getValue());
+                        list.add(zeroMap);
+                    }
+                }
             } else {
                 // 默认查询所有行业
                 for (Supplier<List<DeviceSummaryVO>> supplier : serviceMap.values()) {
@@ -81,7 +108,6 @@ public class PlatformDeviceApi extends BaseController {
             log.error("获取设备汇总信息异常: ", e);
             return AjaxResult.error("系统异常,请稍后再试");
         }
-
         return AjaxResult.success(list);
     }
 
@@ -107,6 +133,22 @@ public class PlatformDeviceApi extends BaseController {
     }
 
     /**
+     * 创建零值设备汇总数据
+     * @param industryName 行业名称
+     * @return 包含零值数据的Map
+     */
+    private Map<String, Object> createZeroDeviceSummary(String industryName) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("industryName", industryName);
+        map.put("deviceTotal", "0");
+        map.put("onlineCount", "0");
+        map.put("offlineCount", "0");
+        map.put("onlinePercent", "0%");
+        map.put("offlinePercent", "0%");
+        return map;
+    }
+
+    /**
      * 设备类型接口
      */
     @RequestMapping("/getDeviceType")
@@ -189,115 +231,451 @@ public class PlatformDeviceApi extends BaseController {
     @RequestMapping("/getDeviceList")
     public TableDataInfo getDeviceList(@RequestParam(value = "industry", required = true) int industry) {
         List<DeviceListVO> list = new ArrayList<>();
+        
         switch(industry) {
             case 1:
-                List<GasDeviceBaseInfoData> gasDeviceBaseInfoDataList = this.gasDeviceBaseInfoDataService.selectGasDeviceBaseInfoDataList(new GasDeviceBaseInfoData());
-                for(GasDeviceBaseInfoData gasDeviceBaseInfoData : gasDeviceBaseInfoDataList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("燃气");
-                    deviceListVO.setDeviceName(gasDeviceBaseInfoData.getDeviceName());
-                    deviceListVO.setLongitude(gasDeviceBaseInfoData.getLng());
-                    deviceListVO.setLatitude(gasDeviceBaseInfoData.getLat());
-                    if(gasDeviceBaseInfoData.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getGasDeviceList();
                 break;
             case 2:
-                List<DrainageDeviceBaseInfoData> drainageDeviceBaseInfoDataList = this.drainageDeviceBaseInfoDataService.selectDrainageDeviceBaseInfoDataList(new DrainageDeviceBaseInfoData());
-                for(DrainageDeviceBaseInfoData drainageDeviceBaseInfoData : drainageDeviceBaseInfoDataList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("排水");
-                    deviceListVO.setDeviceName(drainageDeviceBaseInfoData.getDeviceName());
-                    deviceListVO.setLongitude(drainageDeviceBaseInfoData.getLongitude());
-                    deviceListVO.setLatitude(drainageDeviceBaseInfoData.getLatitude());
-                    if (drainageDeviceBaseInfoData.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getDrainageDeviceList();
                 break;
             case 3:
-                List<HeatingDevice> heatingDeviceList = this.heatingDeviceService.selectDeviceList(new HeatingDevice());
-                for(HeatingDevice heatingDevice : heatingDeviceList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("供热");
-                    deviceListVO.setDeviceName(heatingDevice.getDeviceName());
-                    deviceListVO.setLongitude(heatingDevice.getLongitude());
-                    deviceListVO.setLatitude(heatingDevice.getLatitude());
-                    if (heatingDevice.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getHeatingDeviceList();
                 break;
             case 4:
-                List<BridgeDevice> bridgeDeviceList = this.bridgeDeviceService.selectDeviceList(new BridgeDevice());
-                for(BridgeDevice bridgeDevice : bridgeDeviceList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("桥梁");
-                    deviceListVO.setDeviceName(bridgeDevice.getDeviceName());
-                    deviceListVO.setLongitude(bridgeDevice.getLongitude());
-                    deviceListVO.setLatitude(bridgeDevice.getLatitude());
-                    if (bridgeDevice.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getBridgeDeviceList();
                 break;
             case 5:
-                List<WaterSupplyDeviceBaseInfo> waterSupplyDeviceBaseInfoList = this.waterSupplyDeviceBaseInfoService.selectWaterSupplyDeviceBaseInfoList(new WaterSupplyDeviceBaseInfo());
-                for(WaterSupplyDeviceBaseInfo waterSupplyDeviceBaseInfo : waterSupplyDeviceBaseInfoList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("供水");
-                    deviceListVO.setDeviceName(waterSupplyDeviceBaseInfo.getDeviceName());
-                    deviceListVO.setLongitude(waterSupplyDeviceBaseInfo.getLng());
-                    deviceListVO.setLatitude(waterSupplyDeviceBaseInfo.getLat());
-                    if (waterSupplyDeviceBaseInfo.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getWaterSupplyDeviceList();
                 break;
             case 6:
-                List<UtilityTunnelDevice> utilityTunnelDeviceList = this.utilityTunnelDeviceService.selectDeviceList(new UtilityTunnelDevice());
-                for(UtilityTunnelDevice utilityTunnelDevice : utilityTunnelDeviceList) {
-                    DeviceListVO deviceListVO = new DeviceListVO();
-                    deviceListVO.setIndustryName("管廊");
-                    deviceListVO.setDeviceName(utilityTunnelDevice.getDeviceName());
-                    deviceListVO.setLongitude(utilityTunnelDevice.getLongitude());
-                    deviceListVO.setLatitude(utilityTunnelDevice.getLatitude());
-                    if (utilityTunnelDevice.getOnlineStatus().equals("1")) {
-                        deviceListVO.setOnlineStatus("在线");
-                    } else {
-                        deviceListVO.setOnlineStatus("离线");
-                    }
-                    list.add(deviceListVO);
-                }
+                list = getUtilityTunnelDeviceList();
                 break;
             default:
                 break;
         }
+        
         return getDataTable(list);
     }
 
     /**
+     * 获取燃气设备列表
+     */
+    private List<DeviceListVO> getGasDeviceList() {
+        List<GasDeviceBaseInfoData> dataList = gasDeviceBaseInfoDataService.selectGasDeviceBaseInfoDataList(new GasDeviceBaseInfoData());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("燃气", device.getDeviceName(), 
+                        device.getLng(), device.getLat(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 获取排水设备列表
+     */
+    private List<DeviceListVO> getDrainageDeviceList() {
+        List<DrainageDeviceBaseInfoData> dataList = drainageDeviceBaseInfoDataService.selectDrainageDeviceBaseInfoDataList(new DrainageDeviceBaseInfoData());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("排水", device.getDeviceName(), 
+                        device.getLongitude(), device.getLatitude(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 获取供热设备列表
+     */
+    private List<DeviceListVO> getHeatingDeviceList() {
+        List<HeatingDevice> dataList = heatingDeviceService.selectDeviceList(new HeatingDevice());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("供热", device.getDeviceName(), 
+                        device.getLongitude(), device.getLatitude(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 获取桥梁设备列表
+     */
+    private List<DeviceListVO> getBridgeDeviceList() {
+        List<BridgeDevice> dataList = bridgeDeviceService.selectDeviceList(new BridgeDevice());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("桥梁", device.getDeviceName(), 
+                        device.getLongitude(), device.getLatitude(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 获取供水设备列表
+     */
+    private List<DeviceListVO> getWaterSupplyDeviceList() {
+        List<WaterSupplyDeviceBaseInfo> dataList = waterSupplyDeviceBaseInfoService.selectWaterSupplyDeviceBaseInfoList(new WaterSupplyDeviceBaseInfo());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("供水", device.getDeviceName(), 
+                        device.getLng(), device.getLat(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 获取管廊设备列表
+     */
+    private List<DeviceListVO> getUtilityTunnelDeviceList() {
+        List<UtilityTunnelDevice> dataList = utilityTunnelDeviceService.selectDeviceList(new UtilityTunnelDevice());
+        return dataList.stream()
+                .map(device -> createDeviceListVO("管廊", device.getDeviceName(), 
+                        device.getLongitude(), device.getLatitude(), device.getOnlineStatus()))
+                .collect(java.util.stream.Collectors.toList());
+    }
+
+    /**
+     * 创建设备列表VO对象
+     * @param industryName 行业名称
+     * @param deviceName 设备名称
+     * @param longitude 经度
+     * @param latitude 纬度
+     * @param onlineStatus 在线状态
+     * @return DeviceListVO对象
+     */
+    private DeviceListVO createDeviceListVO(String industryName, String deviceName, 
+                                             String longitude, String latitude, String onlineStatus) {
+        DeviceListVO vo = new DeviceListVO();
+        vo.setIndustryName(industryName);
+        vo.setDeviceName(deviceName);
+        vo.setLongitude(longitude);
+        vo.setLatitude(latitude);
+        vo.setOnlineStatus("1".equals(onlineStatus) ? "在线" : "离线");
+        return vo;
+    }
+
+    /**
      * 设备运行状态接口
      */
 
     /**
      * 设备报警接口
      */
+    @RequestMapping("/deviceAlarm")
+    public AjaxResult deviceAlarm(@RequestParam(value = "timegran", required = true) int timegran,
+                                  @RequestParam(value = "industry", required = true) int industry) {
+        List<Map<String, Object>> result = new ArrayList<>();
+        // 定义行业信息映射
+        Map<Integer, IndustryInfo> industryMap = new HashMap<>();
+        industryMap.put(1, new IndustryInfo("燃气", "gas_device_type", gasDeviceBaseInfoDataService::getDeviceEventAlarmList));
+        industryMap.put(2, new IndustryInfo("排水", "drainage_device_type", drainageDeviceBaseInfoDataService::getDeviceEventAlarmList));
+        industryMap.put(3, new IndustryInfo("供热", "heating_device_type", heatingDeviceService::getDeviceEventAlarmList));
+        industryMap.put(4, new IndustryInfo("桥梁", "bridge_device_type", bridgeDeviceService::getDeviceEventAlarmList));
+        industryMap.put(5, new IndustryInfo("供水", "water_device_type", waterSupplyDeviceBaseInfoService::getDeviceEventAlarmList));
+        industryMap.put(6, new IndustryInfo("管廊", "utilitytunnel_device_type", utilityTunnelDeviceService::getDeviceEventAlarmList));
+        if (!industryMap.containsKey(industry)) {
+            return AjaxResult.success(result);
+        }
+        IndustryInfo info = industryMap.get(industry);
+        try {
+            switch (timegran) {
+                case 1:
+                    // 按照周统计
+                    processWeeklyData(info, result);
+                    break;
+                case 2:
+                    // 按照月统计
+                    processMonthlyData(info, result);
+                    break;
+                case 3:
+                    // 按照季统计
+                    processQuarterlyData(info, result);
+                    break;
+                default:
+                    // 按照年统计
+                    processYearlyData(info, result);
+                    break;
+            }
+        } catch (Exception e) {
+            log.error("获取设备报警信息异常: industry={}, timegran={}", industry, timegran, e);
+            return AjaxResult.error("系统异常,请稍后再试");
+        }
+        return AjaxResult.success(result);
+    }
 
+    /**
+     * 行业信息封装类
+     */
+    private static class IndustryInfo {
+        private final String industryName;
+        private final String dictType;
+        private final BiFunction<String, String, List<DeviceEventAlarmVO>> dataFetcher;
+        public IndustryInfo(String industryName, String dictType,
+                            BiFunction<String, String, List<DeviceEventAlarmVO>> dataFetcher) {
+            this.industryName = industryName;
+            this.dictType = dictType;
+            this.dataFetcher = dataFetcher;
+        }
+    }
+
+    /**
+     * 处理周统计数据
+     */
+    private void processWeeklyData(IndustryInfo info, List<Map<String, Object>> result) {
+        List<Map<String, String>> list = getOneWeekDatesInfo();
+        for (Map<String, String> map : list) {
+            List<DeviceEventAlarmVO> tempList = info.dataFetcher.apply(map.get("date"), map.get("date"));
+            Map<String, Object> item = new HashMap<>();
+            item.put("industryName", info.industryName);
+            item.put("date", map.get("date"));
+            item.put("dayOfWeek", map.get("dayOfWeek"));
+            List<DeviceEventAlarmVO> resultList = buildResultList(tempList, info.dictType);
+            item.put("dataList", resultList);
+            result.add(item);
+        }
+    }
+
+    /**
+     * 处理月统计数据
+     */
+    private void processMonthlyData(IndustryInfo info, List<Map<String, Object>> result) {
+        List<String> mdlist = getCurrentMonthDates();
+        for (String date : mdlist) {
+            List<DeviceEventAlarmVO> tempList = info.dataFetcher.apply(date, date);
+            Map<String, Object> item = new HashMap<>();
+            item.put("industryName", info.industryName);
+            item.put("date", date);
+            List<DeviceEventAlarmVO> resultList = buildResultList(tempList, info.dictType);
+            item.put("dataList", resultList);
+            result.add(item);
+        }
+    }
+
+    /**
+     * 处理季度统计数据
+     */
+    private void processQuarterlyData(IndustryInfo info, List<Map<String, Object>> result) {
+        List<Map<String, String>> yqlist = getPreviousFourQuarters();
+        for (Map<String, String> map : yqlist) {
+            List<DeviceEventAlarmVO> tempList = info.dataFetcher.apply(map.get("startDate"), map.get("endDate"));
+            Map<String, Object> item = new HashMap<>();
+            item.put("industryName", info.industryName);
+            item.put("name", map.get("name"));
+            List<DeviceEventAlarmVO> resultList = buildResultList(tempList, info.dictType);
+            item.put("dataList", resultList);
+            result.add(item);
+        }
+    }
+
+    /**
+     * 处理年度统计数据
+     */
+    private void processYearlyData(IndustryInfo info, List<Map<String, Object>> result) {
+        List<Map<String, String>> ymlist = getCurrentYearMonths();
+        for (Map<String, String> map : ymlist) {
+            List<DeviceEventAlarmVO> tempList = info.dataFetcher.apply(map.get("startDate"), map.get("endDate"));
+            Map<String, Object> item = new HashMap<>();
+            item.put("industryName", info.industryName);
+            item.put("name", map.get("name"));
+            List<DeviceEventAlarmVO> resultList = buildResultList(tempList, info.dictType);
+            item.put("dataList", resultList);
+            result.add(item);
+        }
+    }
+
+    /**
+     * 构建结果列表
+     */
+    private List<DeviceEventAlarmVO> buildResultList(List<DeviceEventAlarmVO> sourceList, String dictType) {
+        List<DeviceEventAlarmVO> resultList = new ArrayList<>();
+        if (sourceList != null) {
+            for (DeviceEventAlarmVO vo : sourceList) {
+                DeviceEventAlarmVO resultVO = new DeviceEventAlarmVO();
+                resultVO.setDeviceType(DictUtils.getDictDataByValue(dictType, vo.getDeviceType()));
+                resultVO.setTypeCount(vo.getTypeCount());
+                resultList.add(resultVO);
+            }
+        }
+        return resultList;
+    }
+
+    /**
+     * 根据当前日期返回向前推一周的每一天日期和星期几
+     * @return 包含一周内每天日期和星期信息的List
+     */
+    private List<Map<String, String>> getOneWeekDatesInfo() {
+        List<Map<String, String>> result = new ArrayList<>();
+        // 获取当前日期
+        Calendar calendar = Calendar.getInstance();
+        // 向前推一周
+        calendar.add(Calendar.WEEK_OF_YEAR, -1);
+        // 格式化日期
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // 星期数组
+        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
+        // 循环7天,获取一周内的每一天
+        for (int i = 0; i < 8; i++) {
+            Map<String, String> dayInfo = new HashMap<>();
+            // 获取当前日期字符串
+            String dateStr = dateFormat.format(calendar.getTime());
+            // 获取星期几
+            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+            String dayOfWeekStr = weekDays[dayOfWeek];
+            dayInfo.put("date", dateStr);
+            dayInfo.put("dayOfWeek", dayOfWeekStr);
+            result.add(dayInfo);
+            // 日期加一天
+            calendar.add(Calendar.DAY_OF_YEAR, 1);
+        }
+        return result;
+    }
+
+    /**
+     * 根据当前日期返回当月每一天的日期列表
+     * @return 包含当月每天日期的List
+     */
+    private List<String> getCurrentMonthDates() {
+        List<String> result = new ArrayList<>();
+        // 获取当前日期
+        Calendar calendar = Calendar.getInstance();
+        // 设置为当前月的第一天
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        // 格式化日期
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // 获取当前月的最大天数
+        int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        // 循环添加当月每一天
+        for (int i = 1; i <= maxDay; i++) {
+            calendar.set(Calendar.DAY_OF_MONTH, i);
+            result.add(dateFormat.format(calendar.getTime()));
+        }
+        return result;
+    }
+
+    /**
+     * 根据当前日期向前推出四个季度,返回每个季度的名称和开始结束日期
+     * @return 包含四个季度信息的List
+     */
+    private List<Map<String, String>> getPreviousFourQuarters() {
+        List<Map<String, String>> result = new ArrayList<>();
+        // 获取当前日期
+        Calendar calendar = Calendar.getInstance();
+        // 格式化日期
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // 季度名称数组
+        String[] quarterNames = {"春季", "夏季", "秋季", "冬季"};
+        // 计算当前季度
+        int currentMonth = calendar.get(Calendar.MONTH) + 1; // 月份从0开始,需要+1
+        int currentQuarter = (currentMonth - 1) / 3 + 1;
+        // 获取当前年份
+        int currentYear = calendar.get(Calendar.YEAR);
+        // 向前推四个季度
+        for (int i = 3; i >= 0; i--) {
+            Map<String, String> quarterInfo = new HashMap<>();
+            // 计算目标季度和年份
+            int targetQuarter = currentQuarter - i;
+            int targetYear = currentYear;
+            // 处理跨年情况
+            while (targetQuarter <= 0) {
+                targetQuarter += 4;
+                targetYear--;
+            }
+            // 确保季度在1-4范围内
+            if (targetQuarter > 4) {
+                targetQuarter -= 4;
+            }
+            // 设置季度名称
+            String quarterName = quarterNames[targetQuarter - 1];
+            // 计算季度开始月份和结束月份
+            int startMonth = (targetQuarter - 1) * 3 + 1;  // 季度开始月份
+            int endMonth = targetQuarter * 3;              // 季度结束月份
+            // 设置季度开始日期 (季度第一个月的第一天)
+            Calendar startCalendar = Calendar.getInstance();
+            startCalendar.set(targetYear, startMonth - 1, 1); // 月份从0开始计算
+            String startDate = dateFormat.format(startCalendar.getTime());
+            // 设置季度结束日期 (季度最后一个月的最后一天)
+            Calendar endCalendar = Calendar.getInstance();
+            endCalendar.set(targetYear, endMonth - 1, 1);
+            endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+            String endDate = dateFormat.format(endCalendar.getTime());
+            quarterInfo.put("name", quarterName);
+            quarterInfo.put("startDate", startDate);
+            quarterInfo.put("endDate", endDate);
+            result.add(quarterInfo);
+        }
+        return result;
+    }
+
+    /**
+     * 根据当前日期返回本年度12个月的名称和每个月的开始日期和结束日期
+     * @return 包含12个月信息的List
+     */
+    private List<Map<String, String>> getCurrentYearMonths() {
+        List<Map<String, String>> result = new ArrayList<>();
+        // 获取当前日期
+        Calendar calendar = Calendar.getInstance();
+        // 获取当前年份
+        int currentYear = calendar.get(Calendar.YEAR);
+        // 格式化日期
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // 循环处理12个月
+        for (int month = 1; month <= 12; month++) {
+            Map<String, String> monthInfo = new HashMap<>();
+            // 设置月份名称
+            String monthName = month + "月";
+            // 设置月开始日期 (月份的第一天)
+            Calendar startCalendar = Calendar.getInstance();
+            startCalendar.set(currentYear, month - 1, 1); // 月份从0开始计算
+            String startDate = dateFormat.format(startCalendar.getTime());
+            // 设置月结束日期 (月份的最后一天)
+            Calendar endCalendar = Calendar.getInstance();
+            endCalendar.set(currentYear, month - 1, 1);
+            endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+            String endDate = dateFormat.format(endCalendar.getTime());
+            monthInfo.put("name", monthName);
+            monthInfo.put("startDate", startDate);
+            monthInfo.put("endDate", endDate);
+            result.add(monthInfo);
+        }
+        return result;
+    }
+
+    /**
+     * 获取告警设备列表
+     */
+    @GetMapping("/getDeviceEventList")
+    public TableDataInfo getDeviceEventList(@RequestParam(value = "industry", required = true) int industry,
+                                            @RequestParam(value = "eventTitle", required = false) String eventTitle,
+                                            @RequestParam(value = "createTimeRange", required = false) String createTimeRange) {
+        EventSubjectQueryVO queryVO = new EventSubjectQueryVO();
+        if(eventTitle != null && !"".equals(eventTitle)) {
+            queryVO.setEventTitle(eventTitle);
+        }
+        if(createTimeRange != null && !"".equals(createTimeRange)) {
+            List<String> createTimeRangeList = new ArrayList<>();
+            createTimeRangeList.add(createTimeRange+" 00:00:00");
+            createTimeRangeList.add(createTimeRange+" 23:59:59");
+            queryVO.setCreateTimeRange(createTimeRangeList);
+        }
+        switch (industry) {
+            case 1:
+                // 燃气
+                queryVO.setEventTypeCode("23");
+                break;
+            case 2:
+                // 排水
+                queryVO.setEventTypeCode("6");
+                break;
+            case 3:
+                // 供热
+                queryVO.setEventTypeCode("5");
+                break;
+            case 4:
+                // 桥梁
+                queryVO.setEventTypeCode("null");
+                break;
+            case 5:
+                // 供水
+                queryVO.setEventTypeCode("8");
+                break;
+            case 6:
+                // 管廊
+                queryVO.setEventTypeCode("7");
+                break;
+            default:
+                queryVO.setEventTypeCode("");
+        }
+        List<EventSubjectBO> result = this.eventSubjectService.getTotalEventList(queryVO);
+        return getDataTable(result);
+    }
 }

+ 29 - 0
src/main/java/com/sooka/sponest/construction/api/PlatformRiskRegister.java

@@ -0,0 +1,29 @@
+package com.sooka.sponest.construction.api;
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.sooka.sponest.construction.community.service.IBuildingService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/platformRiskRegister")
+public class PlatformRiskRegister extends BaseController {
+
+    @Autowired
+    private IBuildingService buildingService;
+
+    /**
+     * 根据街道社区名称统计住宅数量
+     * @return
+     */
+    @GetMapping("/getStreetCommHouseCount")
+    public TableDataInfo getStreetCommHouseCount() {
+        return getDataTable(this.buildingService.getStreetCommHouseCount());
+    }
+
+}

+ 621 - 0
src/main/java/com/sooka/sponest/construction/api/PlatformUtilityTunnel.java

@@ -0,0 +1,621 @@
+package com.sooka.sponest.construction.api;
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.security.utils.DictUtils;
+import com.sooka.sponest.construction.api.vo.*;
+import com.sooka.sponest.construction.utilityTunnel.service.IUtilityTunnelBodyInformationService;
+import com.sooka.sponest.construction.utilityTunnel.service.IUtilityTunnelHiddendangerService;
+import com.sooka.sponest.construction.utilityTunnel.service.IUtilityTunnelManholeService;
+import com.sooka.sponest.construction.utilityTunnel.service.IUtilityTunnelPipeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RestController
+@RequestMapping("/api/platformUtility")
+public class PlatformUtilityTunnel extends BaseController {
+
+    @Autowired
+    private IUtilityTunnelBodyInformationService utilityTunnelBodyInformationService;
+
+    @Autowired
+    private IUtilityTunnelPipeService utilityTunnelPipeService;
+
+    @Autowired
+    private IUtilityTunnelHiddendangerService utilityTunnelHiddendangerService;
+
+    @Autowired
+    private IUtilityTunnelManholeService utilityTunnelManholeService;
+
+    /**
+     * 根据区划统计各类别管廊数量(原始数据格式)
+     * @return
+     */
+    @GetMapping("/getDivCatUtilityTunnelCount")
+    public TableDataInfo getDivCatUtilityTunnelCount() {
+        List<DivCatUtilityTunnelCountVO> result = this.utilityTunnelBodyInformationService.getDivCatUtilityTunnelCount()
+                .stream()
+                .map(item -> {
+                    DivCatUtilityTunnelCountVO vo = new DivCatUtilityTunnelCountVO();
+                    vo.setDivName(item.getDivName());
+                    vo.setCatName(DictUtils.getDictDataByValue("utilityTunnel_body_type", item.getCatName()));
+                    vo.setPipeCount(item.getPipeCount());
+                    return vo;
+                })
+                .collect(Collectors.toList());
+        return getDataTable(result);
+    }
+
+    /**
+     * 根据区划统计各类别管廊数量(柱状图、折线图图表格式)
+     * @return
+     */
+    @GetMapping("/getDivCatUtCountChart")
+    public AjaxResult getDivCatUtCountChart() {
+        List<DivCatUtilityTunnelCountVO> dataList = this.utilityTunnelBodyInformationService.getDivCatUtilityTunnelCount();
+        // 获取所有唯一的区划名称(xdata)
+        List<String> xdata = dataList.stream()
+                .map(DivCatUtilityTunnelCountVO::getDivName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 获取所有唯一的类别名称
+        List<String> categories = dataList.stream()
+                .map(DivCatUtilityTunnelCountVO::getCatName)
+                .distinct()
+                .collect(Collectors.toList());
+        // 构建ydata:按类别分组,每个类别包含在各区划的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = categories.stream()
+                .map(category -> {
+                    // 获取该类别的字典翻译名称
+                    String catDisplayName = DictUtils.getDictDataByValue("utilityTunnel_body_type", category);
+                    // 为每个区划填充该类别的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(divName -> dataList.stream()
+                                    .filter(item -> item.getDivName().equals(divName) && item.getCatName().equals(category))
+                                    .findFirst()
+                                    .map(DivCatUtilityTunnelCountVO::getPipeCount)
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(catDisplayName, values);
+                })
+                .collect(Collectors.toList());
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 获取管廊材质统计数据(原始数据格式)
+     * @return
+     */
+    @GetMapping("/getUtilityTunnelMatCountByType")
+    public TableDataInfo getUtilityTunnelMatCountByType() {
+        List<UtilityTunnelMatCountByTypeVO> result = this.utilityTunnelBodyInformationService.getUtilityTunnelMatCountByType()
+                .stream()
+                .map(item -> {
+                    UtilityTunnelMatCountByTypeVO vo = new UtilityTunnelMatCountByTypeVO();
+                    vo.setTunnelCategory(DictUtils.getDictDataByValue("utilityTunnel_body_type", item.getTunnelCategory()));
+                    vo.setMaterial(item.getMaterial());
+                    vo.setUseCount(item.getUseCount());
+                    return vo;
+                })
+                .collect(Collectors.toList());
+        return getDataTable(result);
+    }
+
+    /**
+     * 根据管廊类别统计各材质使用数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getUtilityTunnelMatCountChart")
+    public AjaxResult getUtilityTunnelMatCountChart() {
+        List<UtilityTunnelMatCountByTypeVO> dataList = this.utilityTunnelBodyInformationService.getUtilityTunnelMatCountByType();
+        // 获取所有唯一的材质(xdata)
+        List<String> xdata = dataList.stream()
+                .map(UtilityTunnelMatCountByTypeVO::getMaterial)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 获取所有唯一的管廊类型
+        List<String> tunnelCategories = dataList.stream()
+                .map(UtilityTunnelMatCountByTypeVO::getTunnelCategory)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+        // 构建ydata:按管廊类型分组,每个类型包含在各材质的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = tunnelCategories.stream()
+                .map(category -> {
+                    // 获取该类型的字典翻译名称
+                    String categoryDisplayName = DictUtils.getDictDataByValue("utilityTunnel_body_type", category);
+                    // 为每个材质填充该管廊类型的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(material -> dataList.stream()
+                                    .filter(item -> material.equals(item.getMaterial()) 
+                                            && category.equals(item.getTunnelCategory()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getUseCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(categoryDisplayName, values);
+                })
+                .collect(Collectors.toList());
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据深埋类型统计各压力级别管廊数量
+     * @return
+     */
+    /**
+     * 获取埋深类型与压力级别统计数据(原始数据格式)
+     * @return
+     */
+    @GetMapping("/getUtPressureCountByBuriedType")
+    public TableDataInfo getUtPressureCountByBuriedType() {
+        return getDataTable(this.utilityTunnelBodyInformationService.getUtPressureCountByBuriedType());
+    }
+
+    /**
+     * 获取埋深类型与压力级别统计数据(图表格式)
+     * @return
+     */
+    @GetMapping("/getUtPressureCountChart")
+    public AjaxResult getUtPressureCountChart() {
+        List<UtPressureCountByBuriedTypeVO> dataList = this.utilityTunnelBodyInformationService.getUtPressureCountByBuriedType();
+
+        // 获取所有唯一的埋深类型(xdata)
+        List<String> xdata = dataList.stream()
+                .map(UtPressureCountByBuriedTypeVO::getBuriedType)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的压力级别
+        List<String> pressureLevels = dataList.stream()
+                .map(UtPressureCountByBuriedTypeVO::getPressureLevel)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按压力级别分组,每个压力级别包含在各埋深类型的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = pressureLevels.stream()
+                .map(pressureLevel -> {
+                    // 为每个埋深类型填充该压力级别的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(buriedType -> dataList.stream()
+                                    .filter(item -> buriedType.equals(item.getBuriedType()) 
+                                            && pressureLevel.equals(item.getPressureLevel()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getUseCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+
+                    return new EChartsBarLineChartVO.SeriesData(pressureLevel, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    @GetMapping("/getYearPipeAgeCount")
+    public TableDataInfo getYearPipeAgeCount() {
+        return getDataTable(this.utilityTunnelBodyInformationService.getYearPipeAgeCount());
+    }
+
+    /**
+     *根据上报时间统计实际整改时间
+     * @return
+     */
+    @GetMapping("/getReportActualFixDate")
+    public TableDataInfo getReportActualFixDate() {
+        // 使用 SimpleDateFormat 格式化当前日期
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String currentDate = sdf.format(new Date());
+        return getDataTable(this.utilityTunnelHiddendangerService.getReportActualFixDate(getThirtyDaysAgo(LocalDate.now()), currentDate));
+    }
+    // 获取当前日期的 30 天前的日期
+    private String getThirtyDaysAgo(LocalDate date) {
+        LocalDate thirtyDaysAgo = date.minusDays(30);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        return thirtyDaysAgo.format(formatter);
+    }
+
+    /**
+     * 根据区划统计各类型隐患数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getDistrictDangerTypeCountChart")
+    public AjaxResult getDistrictDangerTypeCountChart() {
+        List<DistrictDangerTypeCountVO> dataList = this.utilityTunnelHiddendangerService.getDistrictDangerTypeCount();
+
+        // 获取所有唯一的区划名称(xdata)
+        List<String> xdata = dataList.stream()
+                .map(DistrictDangerTypeCountVO::getDivName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的隐患类型
+        List<String> dangerTypes = dataList.stream()
+                .map(DistrictDangerTypeCountVO::getDangerType)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按隐患类型分组,每个类型包含在各区划的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = dangerTypes.stream()
+                .map(type -> {
+                    // 获取该类型的字典翻译名称
+                    String categoryDisplayName = DictUtils.getDictDataByValue("items_type", type);
+                    // 为每个区划填充该隐患类型的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(divName -> dataList.stream()
+                                    .filter(item -> item.getDivName().equals(divName) && item.getDangerType().equals(type))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getDangerCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(categoryDisplayName, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     *根据安装日期统计井室规格
+     * @return
+     */
+    @GetMapping("/getInstallDateChamberSpecCount")
+    public TableDataInfo getInstallDateChamberSpecCount() {
+        return getDataTable(this.utilityTunnelManholeService.getInstallDateChamberSpecCount());
+    }
+
+    /**
+     * 根据安装日期统计井室规格数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getInstallDateChamberSpecCountChart")
+    public AjaxResult getInstallDateChamberSpecCountChart() {
+        List<InstallDateChamberSpecCountVO> dataList = this.utilityTunnelManholeService.getInstallDateChamberSpecCount();
+
+        // 获取所有唯一的安装日期(xdata)
+        List<String> xdata = dataList.stream()
+                .map(InstallDateChamberSpecCountVO::getInstallDate)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的井室规格
+        List<String> chamberSpecs = dataList.stream()
+                .map(InstallDateChamberSpecCountVO::getChamberSpec)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按井室规格分组,每个规格包含在各安装日期的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = chamberSpecs.stream()
+                .map(spec -> {
+                    // 为每个安装日期填充该井室规格的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(installDate -> dataList.stream()
+                                    .filter(item -> installDate.equals(item.getInstallDate())
+                                            && spec.equals(item.getChamberSpec()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getChamberCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(spec, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+
+    /**
+     * 根据井盖材质统计检修井材质数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getCoverManholeMaterialCountChart")
+    public AjaxResult getCoverManholeMaterialCountChart() {
+        List<CoverManholeMaterialCountVO> dataList = this.utilityTunnelManholeService.getCoverManholeMaterialCount();
+
+        // 获取所有唯一的井盖材质(xdata)
+        List<String> xdata = dataList.stream()
+                .map(CoverManholeMaterialCountVO::getMaterial)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的检修井类型
+        List<String> manholeTypes = dataList.stream()
+                .map(CoverManholeMaterialCountVO::getRepairMaterial)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按检修井类型分组,每个类型包含在各井盖材质的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = manholeTypes.stream()
+                .map(type -> {
+                    // 为每个井盖材质填充该检修井类型的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(coverMaterial -> dataList.stream()
+                                    .filter(item -> coverMaterial.equals(item.getMaterial()) && type.equals(item.getRepairMaterial()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getRepairCount()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(type, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    @GetMapping("/getDistrictCoverShapeMatCount")
+    public TableDataInfo getDistrictCoverShapeMatCount() {
+        return getDataTable(this.utilityTunnelManholeService.getDistrictCoverShapeMatCount());
+    }
+
+    /**
+     * 根据区划统计井盖形状和材质数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getDistrictCoverShapeMatCountChart")
+    public AjaxResult getDistrictCoverShapeMatCountChart() {
+        List<DistrictCoverShapeMatCountVO> dataList = this.utilityTunnelManholeService.getDistrictCoverShapeMatCount();
+
+        // 获取所有唯一的区划名称(ydata)
+        List<String> ydata = dataList.stream()
+                .map(DistrictCoverShapeMatCountVO::getDistrictName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的井盖形状+材质组合(xdata)
+        List<String> xdata = dataList.stream()
+                .map(item -> item.getCoverShape() + "、" + item.getCoverMaterial())
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 构建series data:按区划分组,每个区划包含在各形状+材质组合的数量
+        List<EChartsBarLineChartVO.SeriesData> seriesData = ydata.stream()
+                .map(district -> {
+                    // 为每个形状+材质组合填充该区划的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(shapeMaterial -> dataList.stream()
+                                    .filter(item -> (item.getCoverShape() + "、" + item.getCoverMaterial()).equals(shapeMaterial)
+                                            && district.equals(item.getDistrictName()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getCoverCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(district, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, seriesData);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据区划统计管线材质数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getDistrictPipeMaterialCountChart")
+    public AjaxResult getDistrictPipeMaterialCountChart() {
+        List<DistrictPipeMaterialCountVO> dataList = this.utilityTunnelPipeService.getDistrictPipeMaterialCount();
+
+        // 获取所有唯一的管线材质(xdata)
+        List<String> xdata = dataList.stream()
+                .map(DistrictPipeMaterialCountVO::getPipeMaterialName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的区划名称(ydata)
+        List<String> ydata = dataList.stream()
+                .map(DistrictPipeMaterialCountVO::getDistrictName)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 构建series data:按区划分组,每个区划包含在各管道材质的数量
+        List<EChartsBarLineChartVO.SeriesData> seriesData = ydata.stream()
+                .map(district -> {
+                    // 为每个管道材质填充该区划的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(material -> dataList.stream()
+                                    .filter(item -> material.equals(item.getPipeMaterialName())
+                                            && district.equals(item.getDistrictName()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getPipeMaterialCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(district, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, seriesData);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据材质统计压力等级管线数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getMaterialPressureLevelPipeCountChart")
+    public AjaxResult getMaterialPressureLevelPipeCountChart() {
+        List<MaterialPressureLevelPipeCountVO> dataList = this.utilityTunnelPipeService.getMaterialPressureLevelPipeCount();
+
+        // 获取所有唯一的材质(xdata)
+        List<String> xdata = dataList.stream()
+                .map(MaterialPressureLevelPipeCountVO::getMaterial)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的压力等级
+        List<String> pressureLevels = dataList.stream()
+                .map(MaterialPressureLevelPipeCountVO::getPressureLevel)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按压力等级分组,每个压力等级包含在各材质的管线数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = pressureLevels.stream()
+                .map(level -> {
+                    // 为每个材质填充该压力等级的管线数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(material -> dataList.stream()
+                                    .filter(item -> material.equals(item.getMaterial())
+                                            && level.equals(item.getPressureLevel()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getPipeCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(level, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据材质统计保护材质管线数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getMaterialProtectionMatPipeCountChart")
+    public AjaxResult getMaterialProtectionMatPipeCountChart() {
+        List<MaterialProtectionMatPipeCountVO> dataList = this.utilityTunnelPipeService.getMaterialProtectionMatPipeCount();
+
+        // 获取所有唯一的材质(xdata)
+        List<String> xdata = dataList.stream()
+                .map(MaterialProtectionMatPipeCountVO::getMaterial)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的保护材质
+        List<String> protectionMaterials = dataList.stream()
+                .map(MaterialProtectionMatPipeCountVO::getProtectionMaterial)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按保护材质分组,每个保护材质包含在各材质的管线数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = protectionMaterials.stream()
+                .map(protectionMaterial -> {
+                    // 为每个材质填充该保护材质的管线数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(material -> dataList.stream()
+                                    .filter(item -> material.equals(item.getMaterial())
+                                            && protectionMaterial.equals(item.getProtectionMaterial()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getPipeCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(protectionMaterial, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据套管形状统计套管材质数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getCasingShapeMatCountChart")
+    public AjaxResult getCasingShapeMatCountChart() {
+        List<CasingShapeMatCountVO> dataList = this.utilityTunnelPipeService.getCasingShapeMatCount();
+
+        // 获取所有唯一的套管形状(xdata)
+        List<String> matNames = dataList.stream()
+                .map(CasingShapeMatCountVO::getCasingShape)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的套管材质
+        List<String> xdata = dataList.stream()
+                .map(CasingShapeMatCountVO::getMatName)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按套管材质分组,每个材质包含在各套管形状的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = matNames.stream()
+                .map(casingShape -> {
+                    // 为每个套管形状填充该套管材质的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(matName -> dataList.stream()
+                                    .filter(item -> casingShape.equals(item.getCasingShape()) && matName.equals(item.getMatName()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getMatCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(casingShape, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+    /**
+     * 根据埋深年份统计埋深类型数量(图表格式)
+     * @return
+     */
+    @GetMapping("/getBurialYearTypeCountChart")
+    public AjaxResult getBurialYearTypeCountChart() {
+        List<BurialYearTypeCountVO> dataList = this.utilityTunnelPipeService.getBurialYearTypeCount();
+
+        // 获取所有唯一的埋深年份(xdata)
+        List<String> xdata = dataList.stream()
+                .map(BurialYearTypeCountVO::getBurialYear)
+                .distinct()
+                .sorted()
+                .collect(Collectors.toList());
+
+        // 获取所有唯一的埋深类型
+        List<String> buriedTypes = dataList.stream()
+                .map(BurialYearTypeCountVO::getBuriedType)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 构建ydata:按埋深类型分组,每个类型包含在各年份的数量
+        List<EChartsBarLineChartVO.SeriesData> ydata = buriedTypes.stream()
+                .map(type -> {
+                    // 为每个年份填充该埋深类型的数量,如果不存在则为0
+                    List<Integer> values = xdata.stream()
+                            .map(year -> dataList.stream()
+                                    .filter(item -> year.equals(item.getBurialYear())
+                                            && type.equals(item.getBuriedType()))
+                                    .findFirst()
+                                    .map(item -> Integer.parseInt(item.getUseCount().toString()))
+                                    .orElse(0))
+                            .collect(Collectors.toList());
+                    return new EChartsBarLineChartVO.SeriesData(type, values);
+                })
+                .collect(Collectors.toList());
+
+        EChartsBarLineChartVO chartData = new EChartsBarLineChartVO(xdata, ydata);
+        return AjaxResult.success(chartData);
+    }
+
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/BurialYearTypeCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class BurialYearTypeCountVO {
+    // 埋深年
+    private String burialYear;
+    // 埋深类型
+    private String buriedType;
+    // 数量
+    private Integer useCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/CasingShapeMatCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CasingShapeMatCountVO {
+    // 套管形状
+    private String casingShape;
+    // 套管材质
+    private String matName;
+    // 套管材质数量
+    private Integer matCount;
+}

+ 18 - 0
src/main/java/com/sooka/sponest/construction/api/vo/ConstructionYearBridgeTotalLengthVO.java

@@ -0,0 +1,18 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 根据建设年代统计桥梁总长度 的 返回VO
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ConstructionYearBridgeTotalLengthVO {
+    // 建设年代
+    private String constructionYear;
+    // 桥梁总长度
+    private Double bridgeTotalLength;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/ConstructionYearStructureCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ConstructionYearStructureCountVO {
+    // 建设年代
+    private String constructionYear;
+    // 结构类型
+    private String structureType;
+    // 统计数量
+    private String useCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/CoverManholeMaterialCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CoverManholeMaterialCountVO {
+    // 井盖材质
+    private String material;
+    // 检修井材质
+    private String repairMaterial;
+    // 检修井数量
+    private String repairCount;
+}

+ 22 - 0
src/main/java/com/sooka/sponest/construction/api/vo/CrossLenByRegionVO.java

@@ -0,0 +1,22 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CrossLenByRegionVO {
+    // 区划名称
+    private String regionName;
+
+    // 跨数量
+    private Integer crossCount;
+
+    // 跨长度
+    private Double crossLength;
+
+    // 跨平均长度
+    private Double crossAvgLength;
+}

+ 15 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DefectScopeCountByTypeVO.java

@@ -0,0 +1,15 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DefectScopeCountByTypeVO {
+    // 缺陷类型名称
+    private String defectTypeName;
+    // 缺陷数量
+    private Integer defectCount;
+}

+ 13 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DeviceEventAlarmVO.java

@@ -0,0 +1,13 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DeviceEventAlarmVO {
+    private String deviceType; // 设备类型
+    private String typeCount; //类型数量
+}

+ 19 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictCoverShapeMatCountVO.java

@@ -0,0 +1,19 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DistrictCoverShapeMatCountVO {
+    // 区划名称
+    private String districtName;
+    // 井盖形状
+    private String coverShape;
+    // 井盖材质
+    private String coverMaterial;
+    // 井盖数量
+    private Integer coverCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictDangerTypeCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DistrictDangerTypeCountVO {
+    // 区划名称
+    private String divName;
+    // 危险类别名称
+    private String dangerType;
+    // 危险类别数量
+    private String dangerCount;
+}

+ 20 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictDefectTypeCountVO.java

@@ -0,0 +1,20 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 根据区划统计缺损类型数量 的 返回值类型
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DistrictDefectTypeCountVO {
+    // 区划名称
+    private String divName;
+    // 缺陷类型名称
+    private String defectTypeName;
+    // 缺陷数量
+    private Integer defectCount;
+}

+ 19 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictPierCountByTypeVO.java

@@ -0,0 +1,19 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DistrictPierCountByTypeVO {
+    // 区划
+    private String divName;
+
+    // 墩类型
+    private String pierType;
+
+    // 墩数量
+    private String pierCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictPipeMaterialCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DistrictPipeMaterialCountVO {
+    // 区划名称
+    private String districtName;
+    // 管线材质名称
+    private String pipeMaterialName;
+    // 管线材质数量
+    private Integer pipeMaterialCount;
+}

+ 20 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DistrictStructureCountVO.java

@@ -0,0 +1,20 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 根据区划统计桥梁结构
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DistrictStructureCountVO {
+    // 区划名称
+    private String divName;
+    // 结构类型
+    private String structureType;
+    // 结构数量
+    private String structureCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/DivCatUtilityTunnelCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DivCatUtilityTunnelCountVO {
+    // 区划名称
+    private String divName;
+    // 类别名称
+    private String catName;
+    // 管廊数量
+    private Integer pipeCount;
+}

+ 40 - 0
src/main/java/com/sooka/sponest/construction/api/vo/EChartsBarLineChartVO.java

@@ -0,0 +1,40 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * ECharts 柱状图 或 折线图 标准数据格式VO
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class EChartsBarLineChartVO {
+    /**
+     * X轴数据
+     */
+    private List<String> xdata;
+
+    /**
+     * Y轴系列数据
+     */
+    private List<SeriesData> ydata;
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class SeriesData {
+        /**
+         * 系列名称
+         */
+        private String name;
+
+        /**
+         * 系列数据值
+         */
+        private List<Integer> value;
+    }
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/InstallDateChamberSpecCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class InstallDateChamberSpecCountVO {
+    // 安装年份
+    private String installDate;
+    // 井室规格
+    private String chamberSpec;
+    // 井室数量
+    private Integer chamberCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/MaterialPressureLevelPipeCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class MaterialPressureLevelPipeCountVO {
+    // 材质
+    private String material;
+    // 压力等级
+    private String pressureLevel;
+    // 管线数量
+    private Integer pipeCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/MaterialProtectionMatPipeCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class MaterialProtectionMatPipeCountVO {
+    // 材质
+    private String material;
+    // 保护材质
+    private String protectionMaterial;
+    // 管线数量
+    private Integer pipeCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/ReportActualFixDateVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ReportActualFixDateVO {
+    // 上报日期
+    private String reportDate;
+    // 计划修复日期
+    private String planFixDate;
+    // 实际修复日期
+    private String actualFixDate;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/StreetCommHouseCountVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class StreetCommHouseCountVO {
+    // 街道名称
+    private String streetName;
+    // 社区名称
+    private String communityName;
+    // 社区房屋数量
+    private Integer houseCount;
+}

+ 18 - 0
src/main/java/com/sooka/sponest/construction/api/vo/StructureTypeBridgeTotalLengthVO.java

@@ -0,0 +1,18 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 根据桥梁架构统计桥梁总长度
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StructureTypeBridgeTotalLengthVO {
+    // 结构类型
+    private String structureType;
+    // 桥梁总长度
+    private String bridgeTotalLength;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/UtPressureCountByBuriedTypeVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UtPressureCountByBuriedTypeVO {
+    // 埋深类型
+    private String buriedType;
+    // 压力级别
+    private String pressureLevel;
+    // 数量
+    private String useCount;
+}

+ 17 - 0
src/main/java/com/sooka/sponest/construction/api/vo/UtilityTunnelMatCountByTypeVO.java

@@ -0,0 +1,17 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UtilityTunnelMatCountByTypeVO {
+    // 管廊类型
+    private String tunnelCategory;
+    // 材质
+    private String material;
+    // 数量
+    private String useCount;
+}

+ 15 - 0
src/main/java/com/sooka/sponest/construction/api/vo/YearUtPipeAgeCountVO.java

@@ -0,0 +1,15 @@
+package com.sooka.sponest.construction.api.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class YearUtPipeAgeCountVO {
+    // 年限
+    private String pipeAge;
+    // 统计数量
+    private String useCount;
+}

+ 8 - 0
src/main/java/com/sooka/sponest/construction/bridge/domain/BridgeInspectionTaskRecord.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.web.domain.BaseEntity;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
@@ -65,8 +66,15 @@ public class BridgeInspectionTaskRecord extends BaseEntity {
     @ApiModelProperty(value = "任务轨迹", required = false)
     private String taskTrajectory;
 
+    //巡检距离
+    private BigDecimal distance;
+
+    //任务id
     private List<Long> taskIdList;
 
+    //记录id
+    private List<Long> recordList;
+
     private String taskName;
 
 }

+ 6 - 0
src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeAllyCrossPierMapper.java

@@ -1,5 +1,7 @@
 package com.sooka.sponest.construction.bridge.mapper;
 
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DistrictPierCountByTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeAllyCrossPier;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -62,4 +64,8 @@ public interface BridgeAllyCrossPierMapper {
      * @return 结果
      */
     public int deleteBridgeAllyCrossPierByIds(Long[] ids);
+
+    public List<DistrictPierCountByTypeVO> getDistrictPierCountByType();
+
+    public List<CrossLenByRegionVO> getCrossLenByRegion();
 }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeCheckDiseaseMapper.java

@@ -1,5 +1,8 @@
 package com.sooka.sponest.construction.bridge.mapper;
 
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DefectScopeCountByTypeVO;
+import com.sooka.sponest.construction.api.vo.DistrictDefectTypeCountVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeCheckDisease;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -62,4 +65,8 @@ public interface BridgeCheckDiseaseMapper {
      * @return 结果
      */
     public int deleteBridgeCheckDiseaseByIds(Long[] ids);
+
+    public List<DefectScopeCountByTypeVO> getDefectScopeCountByType();
+
+    public List<DistrictDefectTypeCountVO> getDistrictDefectTypeCount();
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeDeviceMapper.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.bridge.mapper;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeDevice;
@@ -77,4 +78,6 @@ public interface BridgeDeviceMapper {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 12 - 0
src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeInfoMapper.java

@@ -1,5 +1,9 @@
 package com.sooka.sponest.construction.bridge.mapper;
 
+import com.sooka.sponest.construction.api.vo.ConstructionYearBridgeTotalLengthVO;
+import com.sooka.sponest.construction.api.vo.ConstructionYearStructureCountVO;
+import com.sooka.sponest.construction.api.vo.DistrictStructureCountVO;
+import com.sooka.sponest.construction.api.vo.StructureTypeBridgeTotalLengthVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeInfo;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -70,4 +74,12 @@ public interface BridgeInfoMapper {
      * @return 结果
      */
     public int deleteBridgeInfoByIds(Long[] ids);
+
+    public List<ConstructionYearBridgeTotalLengthVO> getConstructionYearBridgeTotalLength();
+
+    public List<ConstructionYearStructureCountVO> getConstructionYearStructureCount();
+
+    public List<StructureTypeBridgeTotalLengthVO> getStructureTypeBridgeTotalLength();
+
+    public List<DistrictStructureCountVO> getDistrictStructureCount();
 }

+ 4 - 0
src/main/java/com/sooka/sponest/construction/bridge/mapper/BridgeInspectionTaskRecordMapper.java

@@ -4,6 +4,7 @@ package com.sooka.sponest.construction.bridge.mapper;
 import com.sooka.sponest.construction.bridge.domain.BridgeInspectionTaskRecord;
 import com.sooka.sponest.construction.bridge.domain.BridgeTaskPipe;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -84,4 +85,7 @@ public interface BridgeInspectionTaskRecordMapper {
      * @date 2025/9/12 上午11:16
      */
     public List<BridgeTaskPipe> getBridgePipeByTaskIds(String taskIdList);
+
+    // 计算本次巡检距离
+    public BigDecimal getDistance(Long recordId);
 }

+ 6 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeAllyCrossPierService.java

@@ -1,5 +1,7 @@
 package com.sooka.sponest.construction.bridge.service;
 
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DistrictPierCountByTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeAllyCrossPier;
 
 import java.util.List;
@@ -60,4 +62,8 @@ public interface IBridgeAllyCrossPierService {
      * @return 结果
      */
     public int deleteBridgeAllyCrossPierById(Long id);
+
+    public List<DistrictPierCountByTypeVO> getDistrictPierCountByType();
+
+    public List<CrossLenByRegionVO> getCrossLenByRegion();
 }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeCheckDiseaseService.java

@@ -1,5 +1,8 @@
 package com.sooka.sponest.construction.bridge.service;
 
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DefectScopeCountByTypeVO;
+import com.sooka.sponest.construction.api.vo.DistrictDefectTypeCountVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeCheckDisease;
 
 import java.util.List;
@@ -59,4 +62,8 @@ public interface IBridgeCheckDiseaseService {
      * @return 结果
      */
     public int deleteBridgeCheckDiseaseById(Long id);
+
+    public List<DefectScopeCountByTypeVO> getDefectScopeCountByType();
+
+    public List<DistrictDefectTypeCountVO> getDistrictDefectTypeCount();
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeDeviceService.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.bridge.service;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeDevice;
@@ -76,4 +77,6 @@ public interface IBridgeDeviceService {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate);
 }

+ 12 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/IBridgeInfoService.java

@@ -1,5 +1,9 @@
 package com.sooka.sponest.construction.bridge.service;
 
+import com.sooka.sponest.construction.api.vo.ConstructionYearBridgeTotalLengthVO;
+import com.sooka.sponest.construction.api.vo.ConstructionYearStructureCountVO;
+import com.sooka.sponest.construction.api.vo.DistrictStructureCountVO;
+import com.sooka.sponest.construction.api.vo.StructureTypeBridgeTotalLengthVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeInfo;
 import io.swagger.models.auth.In;
 
@@ -67,4 +71,12 @@ public interface IBridgeInfoService {
      * @return 结果
      */
     public int deleteBridgeInfoById(Long id);
+
+    public List<ConstructionYearBridgeTotalLengthVO> getConstructionYearBridgeTotalLength();
+
+    public List<ConstructionYearStructureCountVO> getConstructionYearStructureCount();
+
+    public List<StructureTypeBridgeTotalLengthVO> getStructureTypeBridgeTotalLength();
+
+    public List<DistrictStructureCountVO> getDistrictStructureCount();
 }

+ 13 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeAllyCrossPierServiceImpl.java

@@ -2,12 +2,15 @@ package com.sooka.sponest.construction.bridge.service.impl;
 
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DistrictPierCountByTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeAllyCrossPier;
 import com.sooka.sponest.construction.bridge.mapper.BridgeAllyCrossPierMapper;
 import com.sooka.sponest.construction.bridge.service.IBridgeAllyCrossPierService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -93,4 +96,14 @@ public class BridgeAllyCrossPierServiceImpl extends BaseServiceImpl implements I
     public int deleteBridgeAllyCrossPierById(Long id) {
         return bridgeAllyCrossPierMapper.deleteBridgeAllyCrossPierById(id);
     }
+
+    @Override
+    public List<DistrictPierCountByTypeVO> getDistrictPierCountByType() {
+        return bridgeAllyCrossPierMapper.getDistrictPierCountByType();
+    }
+
+    @Override
+    public List<CrossLenByRegionVO> getCrossLenByRegion() {
+        return bridgeAllyCrossPierMapper.getCrossLenByRegion();
+    }
 }

+ 13 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeCheckDiseaseServiceImpl.java

@@ -2,6 +2,9 @@ package com.sooka.sponest.construction.bridge.service.impl;
 
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.CrossLenByRegionVO;
+import com.sooka.sponest.construction.api.vo.DefectScopeCountByTypeVO;
+import com.sooka.sponest.construction.api.vo.DistrictDefectTypeCountVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeCheckDisease;
 import com.sooka.sponest.construction.bridge.mapper.BridgeCheckDiseaseMapper;
 import com.sooka.sponest.construction.bridge.service.IBridgeCheckDiseaseService;
@@ -95,4 +98,14 @@ public class BridgeCheckDiseaseServiceImpl extends BaseServiceImpl implements IB
     public int deleteBridgeCheckDiseaseById(Long id) {
         return bridgeCheckDiseaseMapper.deleteBridgeCheckDiseaseById(id);
     }
+
+    @Override
+    public List<DefectScopeCountByTypeVO> getDefectScopeCountByType() {
+        return bridgeCheckDiseaseMapper.getDefectScopeCountByType();
+    }
+
+    @Override
+    public List<DistrictDefectTypeCountVO> getDistrictDefectTypeCount() {
+        return bridgeCheckDiseaseMapper.getDistrictDefectTypeCount();
+    }
 }

+ 2 - 2
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeDeviceMonitoringServiceImpl.java

@@ -94,7 +94,7 @@ public class BridgeDeviceMonitoringServiceImpl implements IBridgeDeviceMonitorin
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String dateStr = sdf.format(new Date());
         //告警报文
-        String title = "【供热设备告警】设备编码:" + deviceCode + ",告警时间:" + dateStr + ";";
+        String title = "【桥梁设备告警】设备编码:" + deviceCode + ",告警时间:" + dateStr + ";";
         String warnText;
         StringBuilder stringBuilder = new StringBuilder(title);
         BridgeDeviceThreshold deviceThreshold = bridgeDeviceThresholdMapper.selectBridgeDeviceThresholdByCode(deviceCode);
@@ -157,7 +157,7 @@ public class BridgeDeviceMonitoringServiceImpl implements IBridgeDeviceMonitorin
                 eventSubjectVO.setLongitude(deviceThreshold.getLongitude());
                 eventSubjectVO.setLatitude(deviceThreshold.getLatitude());
                 eventSubjectVO.setCreateBy(deviceCode);
-                eventSubjectVO.setCreateName(StringUtils.isEmpty(vo.getDeviceName()) ? "供热设备" : vo.getDeviceName());
+                eventSubjectVO.setCreateName(StringUtils.isEmpty(vo.getDeviceName()) ? "桥梁设备" : vo.getDeviceName());
                 eventSubjectVO.setEventSource(EVENT_SOURCE_DEVICE);
                 eventSubjectVO.setEventType(eventType);
                 eventSubjectService.eventReportTransfer(eventSubjectVO);

+ 7 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeDeviceServiceImpl.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.bridge.service.impl;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeDevice;
@@ -11,6 +12,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -116,4 +118,9 @@ public class BridgeDeviceServiceImpl implements IBridgeDeviceService {
     public List<DeviceTypeVO> getDeviceType() {
         return bridgeDeviceMapper.getDeviceType();
     }
+
+    @Override
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate) {
+        return bridgeDeviceMapper.getDeviceEventAlarmList(startDate, endDate);
+    }
 }

+ 24 - 0
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgeInfoServiceImpl.java

@@ -3,6 +3,10 @@ package com.sooka.sponest.construction.bridge.service.impl;
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.domain.BaseBusinessEntity;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.ConstructionYearBridgeTotalLengthVO;
+import com.sooka.sponest.construction.api.vo.ConstructionYearStructureCountVO;
+import com.sooka.sponest.construction.api.vo.DistrictStructureCountVO;
+import com.sooka.sponest.construction.api.vo.StructureTypeBridgeTotalLengthVO;
 import com.sooka.sponest.construction.bridge.domain.BridgeInfo;
 import com.sooka.sponest.construction.bridge.mapper.BridgeInfoMapper;
 import com.sooka.sponest.construction.bridge.service.IBridgeInfoService;
@@ -195,4 +199,24 @@ public class BridgeInfoServiceImpl extends BaseServiceImpl implements IBridgeInf
     public int deleteBridgeInfoById(Long id) {
         return bridgeInfoMapper.deleteBridgeInfoById(id);
     }
+
+    @Override
+    public List<ConstructionYearBridgeTotalLengthVO> getConstructionYearBridgeTotalLength() {
+        return bridgeInfoMapper.getConstructionYearBridgeTotalLength();
+    }
+
+    @Override
+    public List<ConstructionYearStructureCountVO> getConstructionYearStructureCount() {
+        return bridgeInfoMapper.getConstructionYearStructureCount();
+    }
+
+    @Override
+    public List<StructureTypeBridgeTotalLengthVO> getStructureTypeBridgeTotalLength() {
+        return bridgeInfoMapper.getStructureTypeBridgeTotalLength();
+    }
+
+    @Override
+    public List<DistrictStructureCountVO> getDistrictStructureCount() {
+        return bridgeInfoMapper.getDistrictStructureCount();
+    }
 }

+ 23 - 7
src/main/java/com/sooka/sponest/construction/bridge/service/impl/BridgePipeInspectionTaskServiceImpl.java

@@ -8,10 +8,15 @@ import com.sooka.sponest.base.service.impl.BaseServiceImpl;
 import com.sooka.sponest.construction.bridge.domain.*;
 import com.sooka.sponest.construction.bridge.mapper.*;
 import com.sooka.sponest.construction.bridge.service.IBridgePipeInspectionTaskService;
+import com.sooka.sponest.construction.supervisoryPlatform.domain.InspectionMileage;
+import com.sooka.sponest.construction.supervisoryPlatform.mapper.InspectionMileageMapper;
+import io.swagger.models.auth.In;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -171,7 +176,7 @@ public class BridgePipeInspectionTaskServiceImpl extends BaseServiceImpl impleme
      */
     @Override
     public List<Long> startRecord(BridgeInspectionTaskRecord heatingInspectionTaskRecord) {
-        List<Long> taskIdList = new ArrayList<>();
+        List<Long> recordList = new ArrayList<>();
         for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
             //先结束当前用户在当前任务中所有未结束的巡检记录记录
             BridgeInspectionTaskRecord record = new BridgeInspectionTaskRecord();
@@ -188,12 +193,15 @@ public class BridgePipeInspectionTaskServiceImpl extends BaseServiceImpl impleme
             heatingInspectionTaskRecord.setUserName(SecurityUtils.getLoginUser().getSysUser().getNickName());
             //新增巡检任务记录
             heatingInspectionTaskRecordMapper.insertBridgeInspectionTaskRecord(heatingInspectionTaskRecord);
-            taskIdList.add(heatingInspectionTaskRecord.getId());
+            recordList.add(heatingInspectionTaskRecord.getId());
         }
 
-        return taskIdList;
+        return recordList;
     }
 
+    @Resource
+    private InspectionMileageMapper inspectionMileageMapper;
+
     /*
      * 结束巡检
      *
@@ -202,12 +210,20 @@ public class BridgePipeInspectionTaskServiceImpl extends BaseServiceImpl impleme
      */
     @Override
     public int finishRecord(BridgeInspectionTaskRecord heatingInspectionTaskRecord) {
-        for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
-            heatingInspectionTaskRecord.setUserId(SecurityUtils.getLoginUser().getSysUser().getUserId());
-            heatingInspectionTaskRecord.setTaskId(taskId);
+        for (Long recordId : heatingInspectionTaskRecord.getRecordList()) {
+            BigDecimal distance = heatingInspectionTaskRecordMapper.getDistance(recordId);
+            InspectionMileage mileage = new InspectionMileage();
+            mileage.setInspectionId(3L);
+            InspectionMileage mileage1 = inspectionMileageMapper.selectInspectionMileageList(mileage).get(0);
+            mileage1.setMileage(mileage1.getMileage().add(distance));
+            inspectionMileageMapper.updateInspectionMileage(mileage1);
+
+            heatingInspectionTaskRecord.setTaskId(recordId);
             heatingInspectionTaskRecord.setStatus("1");
             heatingInspectionTaskRecord.setEndTime(DateUtils.getNowDate());
-            heatingInspectionTaskRecordMapper.updateBridgeInspectionTaskRecordByUserIdAndTaskId(heatingInspectionTaskRecord);
+            heatingInspectionTaskRecord.setDistance(distance);
+            heatingInspectionTaskRecordMapper.updateBridgeInspectionTaskRecord(heatingInspectionTaskRecord);
+
         }
         return 1;
     }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/community/mapper/BuildingMapper.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.community.mapper;
 
+import com.sooka.sponest.construction.api.vo.StreetCommHouseCountVO;
 import com.sooka.sponest.construction.community.domain.BuildPipe;
 import com.sooka.sponest.construction.community.domain.Building;
 import org.apache.ibatis.annotations.Param;
@@ -84,4 +85,10 @@ public interface BuildingMapper {
      * @date 2025/9/23 上午9:12
      */
     public List<BuildPipe> selectPipeByBuildId(@Param("id") Long id, @Param("type") String type);
+
+    /**
+     * 根据街道社区名称统计住宅数量
+     * @return
+     */
+    List<StreetCommHouseCountVO> getStreetCommHouseCount();
 }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/community/service/IBuildingService.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.community.service;
 
+import com.sooka.sponest.construction.api.vo.StreetCommHouseCountVO;
 import com.sooka.sponest.construction.community.domain.Building;
 
 import java.util.List;
@@ -58,4 +59,10 @@ public interface IBuildingService {
      * @return 结果
      */
     public int deleteBuildingById(Long id);
+
+    /**
+     * 根据街道社区名称统计住宅数量
+     * @return
+     */
+    public List<StreetCommHouseCountVO> getStreetCommHouseCount();
 }

+ 13 - 0
src/main/java/com/sooka/sponest/construction/community/service/impl/BuildingServiceImpl.java

@@ -5,6 +5,7 @@ import com.ruoyi.common.core.utils.SpringUtils;
 import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.security.utils.SecurityUtils;
 import com.ruoyi.system.api.RemoteConfigService;
+import com.sooka.sponest.construction.api.vo.StreetCommHouseCountVO;
 import com.sooka.sponest.construction.community.domain.BuildPipe;
 import com.sooka.sponest.construction.community.domain.Building;
 import com.sooka.sponest.construction.community.domain.CommunityAttach;
@@ -18,6 +19,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -28,11 +30,13 @@ import java.util.List;
  */
 @Service
 public class BuildingServiceImpl implements IBuildingService {
+
     @Autowired
     private BuildingMapper buildingMapper;
 
     @Autowired
     private CommunityMapper communityMapper;
+
     @Autowired
     private CustomersMapper customersMapper;
 
@@ -190,4 +194,13 @@ public class BuildingServiceImpl implements IBuildingService {
     public int deleteBuildingById(Long id) {
         return buildingMapper.deleteBuildingById(id);
     }
+
+    /**
+     * 根据街道社区名称统计住宅数量
+     * @return
+     */
+    @Override
+    public List<StreetCommHouseCountVO> getStreetCommHouseCount() {
+        return buildingMapper.getStreetCommHouseCount();
+    }
 }

+ 8 - 0
src/main/java/com/sooka/sponest/construction/drainage/domain/DrainageInspectionTaskRecord.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.web.domain.BaseEntity;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
@@ -65,8 +66,15 @@ public class DrainageInspectionTaskRecord extends BaseEntity {
     @ApiModelProperty(value = "任务轨迹", required = false)
     private String taskTrajectory;
 
+    //巡检距离
+    private BigDecimal distance;
+
+    //任务id
     private List<Long> taskIdList;
 
+    //记录id
+    private List<Long> recordList;
+
     private String taskName;
 
 }

+ 4 - 0
src/main/java/com/sooka/sponest/construction/drainage/mapper/DrainageDeviceBaseInfoDataMapper.java

@@ -1,9 +1,11 @@
 package com.sooka.sponest.construction.drainage.mapper;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.drainage.domain.DrainageDeviceBaseInfoData;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -72,4 +74,6 @@ public interface DrainageDeviceBaseInfoDataMapper {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/drainage/mapper/DrainageInspectionTaskRecordMapper.java

@@ -4,6 +4,7 @@ package com.sooka.sponest.construction.drainage.mapper;
 import com.sooka.sponest.construction.drainage.domain.DrainageInspectionTaskRecord;
 import com.sooka.sponest.construction.drainage.domain.DrainageTaskPipe;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -84,4 +85,6 @@ public interface DrainageInspectionTaskRecordMapper {
      * @date 2025/9/12 上午11:16
      */
     public List<DrainageTaskPipe> getDrainagePipeByTaskIds(String taskIdList);
+    // 计算本次巡检距离
+    public BigDecimal getDistance(Long recordId);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/drainage/service/IDrainageDeviceBaseInfoDataService.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.drainage.service;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.drainage.domain.DrainageDeviceBaseInfoData;
@@ -70,4 +71,6 @@ public interface IDrainageDeviceBaseInfoDataService {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate);
 }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/drainage/service/impl/DrainageDeviceBaseInfoDataServiceImpl.java

@@ -2,6 +2,7 @@ package com.sooka.sponest.construction.drainage.service.impl;
 
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.drainage.domain.DrainageDeviceBaseInfoData;
@@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -104,4 +106,9 @@ public class DrainageDeviceBaseInfoDataServiceImpl extends BaseServiceImpl imple
     public List<DeviceTypeVO> getDeviceType() {
         return drainageDeviceBaseInfoDataMapper.getDeviceType();
     }
+
+    @Override
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate) {
+        return drainageDeviceBaseInfoDataMapper.getDeviceEventAlarmList(startDate, endDate);
+    }
 }

+ 21 - 8
src/main/java/com/sooka/sponest/construction/drainage/service/impl/DrainagePipeInspectionTaskServiceImpl.java

@@ -8,10 +8,14 @@ import com.sooka.sponest.base.service.impl.BaseServiceImpl;
 import com.sooka.sponest.construction.drainage.domain.*;
 import com.sooka.sponest.construction.drainage.mapper.*;
 import com.sooka.sponest.construction.drainage.service.IDrainagePipeInspectionTaskService;
+import com.sooka.sponest.construction.supervisoryPlatform.domain.InspectionMileage;
+import com.sooka.sponest.construction.supervisoryPlatform.mapper.InspectionMileageMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -171,7 +175,7 @@ public class DrainagePipeInspectionTaskServiceImpl extends BaseServiceImpl imple
      */
     @Override
     public List<Long> startRecord(DrainageInspectionTaskRecord heatingInspectionTaskRecord) {
-        List<Long> taskIdList = new ArrayList<>();
+        List<Long> recordList = new ArrayList<>();
         for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
             //先结束当前用户在当前任务中所有未结束的巡检记录记录
             DrainageInspectionTaskRecord record = new DrainageInspectionTaskRecord();
@@ -188,12 +192,13 @@ public class DrainagePipeInspectionTaskServiceImpl extends BaseServiceImpl imple
             heatingInspectionTaskRecord.setUserName(SecurityUtils.getLoginUser().getSysUser().getNickName());
             //新增巡检任务记录
             heatingInspectionTaskRecordMapper.insertDrainageInspectionTaskRecord(heatingInspectionTaskRecord);
-            taskIdList.add(heatingInspectionTaskRecord.getId());
+            recordList.add(heatingInspectionTaskRecord.getId());
         }
 
-        return taskIdList;
+        return recordList;
     }
-
+    @Resource
+    private InspectionMileageMapper inspectionMileageMapper;
     /*
      * 结束巡检
      *
@@ -202,12 +207,20 @@ public class DrainagePipeInspectionTaskServiceImpl extends BaseServiceImpl imple
      */
     @Override
     public int finishRecord(DrainageInspectionTaskRecord heatingInspectionTaskRecord) {
-        for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
-            heatingInspectionTaskRecord.setUserId(SecurityUtils.getLoginUser().getSysUser().getUserId());
-            heatingInspectionTaskRecord.setTaskId(taskId);
+        for (Long recordId : heatingInspectionTaskRecord.getRecordList()) {
+            BigDecimal distance = heatingInspectionTaskRecordMapper.getDistance(recordId);
+            InspectionMileage mileage = new InspectionMileage();
+            mileage.setInspectionId(2L);
+            InspectionMileage mileage1 = inspectionMileageMapper.selectInspectionMileageList(mileage).get(0);
+            mileage1.setMileage(mileage1.getMileage().add(distance));
+            inspectionMileageMapper.updateInspectionMileage(mileage1);
+
+            heatingInspectionTaskRecord.setTaskId(recordId);
             heatingInspectionTaskRecord.setStatus("1");
             heatingInspectionTaskRecord.setEndTime(DateUtils.getNowDate());
-            heatingInspectionTaskRecordMapper.updateDrainageInspectionTaskRecordByUserIdAndTaskId(heatingInspectionTaskRecord);
+            heatingInspectionTaskRecord.setDistance(distance);
+            heatingInspectionTaskRecordMapper.updateDrainageInspectionTaskRecord(heatingInspectionTaskRecord);
+
         }
         return 1;
     }

+ 91 - 0
src/main/java/com/sooka/sponest/construction/evaluation/controller/PerformanceEvaluationController.java

@@ -0,0 +1,91 @@
+package com.sooka.sponest.construction.evaluation.controller;
+
+import com.ruoyi.common.core.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.sooka.sponest.construction.evaluation.domain.PerformanceEvaluation;
+import com.sooka.sponest.construction.evaluation.service.IPerformanceEvaluationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 考核评价Controller
+ *
+ * @author 韩福成
+ * @date 2025-11-21
+ */
+@RestController
+@RequestMapping("/evaluation")
+public class PerformanceEvaluationController extends BaseController {
+    @Autowired
+    private IPerformanceEvaluationService performanceEvaluationService;
+
+    /**
+     * 查询考核评价列表
+     */
+    @RequiresPermissions("evaluation:evaluation:list")
+    @GetMapping("/list")
+    public TableDataInfo list(PerformanceEvaluation performanceEvaluation) {
+        startPage();
+        List<PerformanceEvaluation> list = performanceEvaluationService.selectPerformanceEvaluationList(performanceEvaluation);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出考核评价列表
+     */
+    @RequiresPermissions("evaluation:evaluation:export")
+    @Log(title = "考核评价", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, PerformanceEvaluation performanceEvaluation) {
+        List<PerformanceEvaluation> list = performanceEvaluationService.selectPerformanceEvaluationList(performanceEvaluation);
+        ExcelUtil<PerformanceEvaluation> util = new ExcelUtil<PerformanceEvaluation>(PerformanceEvaluation.class);
+        util.exportExcel(response, list, "考核评价数据");
+    }
+
+    /**
+     * 获取考核评价详细信息
+     */
+    @RequiresPermissions("evaluation:evaluation:query")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return AjaxResult.success(performanceEvaluationService.selectPerformanceEvaluationById(id));
+    }
+
+    /**
+     * 新增考核评价
+     */
+    @RequiresPermissions("evaluation:evaluation:add")
+    @Log(title = "考核评价", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody PerformanceEvaluation performanceEvaluation) {
+        return toAjax(performanceEvaluationService.insertPerformanceEvaluation(performanceEvaluation));
+    }
+
+    /**
+     * 修改考核评价
+     */
+    @RequiresPermissions("evaluation:evaluation:edit")
+    @Log(title = "考核评价", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody PerformanceEvaluation performanceEvaluation) {
+        return toAjax(performanceEvaluationService.updatePerformanceEvaluation(performanceEvaluation));
+    }
+
+    /**
+     * 删除考核评价
+     */
+    @RequiresPermissions("evaluation:evaluation:remove")
+    @Log(title = "考核评价", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(performanceEvaluationService.deletePerformanceEvaluationByIds(ids));
+    }
+}

+ 57 - 0
src/main/java/com/sooka/sponest/construction/evaluation/domain/PerformanceEvaluation.java

@@ -0,0 +1,57 @@
+package com.sooka.sponest.construction.evaluation.domain;
+
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.datascope.base.domain.BaseBusinessEntity;
+import lombok.Data;
+
+/**
+ * 考核评价对象 performance_evaluation
+ *
+ * @author 韩福成
+ * @date 2025-11-21
+ */
+@Data
+public class PerformanceEvaluation extends BaseBusinessEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 标题
+     */
+    @Excel(name = "标题")
+    private String title;
+
+    /**
+     * 内容
+     */
+    @Excel(name = "内容")
+    private String content;
+
+    /**
+     * 考核周期
+     */
+    @Excel(name = "考核周期")
+    private String cycle;
+
+    /**
+     * 附件地址
+     */
+    @Excel(name = "附件地址")
+    private String fileUrl;
+
+    /**
+     * 附件名称
+     */
+    @Excel(name = "附件名称")
+    private String fileName;
+
+    private String deptId;
+
+    private String deptName;
+
+
+}

+ 62 - 0
src/main/java/com/sooka/sponest/construction/evaluation/mapper/PerformanceEvaluationMapper.java

@@ -0,0 +1,62 @@
+package com.sooka.sponest.construction.evaluation.mapper;
+
+
+import com.sooka.sponest.construction.evaluation.domain.PerformanceEvaluation;
+
+import java.util.List;
+
+/**
+ * 考核评价Mapper接口
+ *
+ * @author 韩福成
+ * @date 2025-11-21
+ */
+public interface PerformanceEvaluationMapper {
+    /**
+     * 查询考核评价
+     *
+     * @param id 考核评价主键
+     * @return 考核评价
+     */
+    public PerformanceEvaluation selectPerformanceEvaluationById(Long id);
+
+    /**
+     * 查询考核评价列表
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 考核评价集合
+     */
+    public List<PerformanceEvaluation> selectPerformanceEvaluationList(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 新增考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    public int insertPerformanceEvaluation(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 修改考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    public int updatePerformanceEvaluation(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 删除考核评价
+     *
+     * @param id 考核评价主键
+     * @return 结果
+     */
+    public int deletePerformanceEvaluationById(Long id);
+
+    /**
+     * 批量删除考核评价
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deletePerformanceEvaluationByIds(Long[] ids);
+}

+ 62 - 0
src/main/java/com/sooka/sponest/construction/evaluation/service/IPerformanceEvaluationService.java

@@ -0,0 +1,62 @@
+package com.sooka.sponest.construction.evaluation.service;
+
+
+import com.sooka.sponest.construction.evaluation.domain.PerformanceEvaluation;
+
+import java.util.List;
+
+/**
+ * 考核评价Service接口
+ *
+ * @author 韩福成
+ * @date 2025-11-21
+ */
+public interface IPerformanceEvaluationService {
+    /**
+     * 查询考核评价
+     *
+     * @param id 考核评价主键
+     * @return 考核评价
+     */
+    public PerformanceEvaluation selectPerformanceEvaluationById(Long id);
+
+    /**
+     * 查询考核评价列表
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 考核评价集合
+     */
+    public List<PerformanceEvaluation> selectPerformanceEvaluationList(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 新增考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    public int insertPerformanceEvaluation(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 修改考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    public int updatePerformanceEvaluation(PerformanceEvaluation performanceEvaluation);
+
+    /**
+     * 批量删除考核评价
+     *
+     * @param ids 需要删除的考核评价主键集合
+     * @return 结果
+     */
+    public int deletePerformanceEvaluationByIds(Long[] ids);
+
+    /**
+     * 删除考核评价信息
+     *
+     * @param id 考核评价主键
+     * @return 结果
+     */
+    public int deletePerformanceEvaluationById(Long id);
+}

+ 142 - 0
src/main/java/com/sooka/sponest/construction/evaluation/service/impl/PerformanceEvaluationServiceImpl.java

@@ -0,0 +1,142 @@
+package com.sooka.sponest.construction.evaluation.service.impl;
+
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.SpringUtils;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.system.api.RemoteConfigService;
+import com.sooka.sponest.construction.evaluation.domain.PerformanceEvaluation;
+import com.sooka.sponest.construction.evaluation.mapper.PerformanceEvaluationMapper;
+import com.sooka.sponest.construction.evaluation.service.IPerformanceEvaluationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static com.sooka.sponest.utils.DataConstants.DOWNLOAD_URL;
+
+/**
+ * 考核评价Service业务层处理
+ *
+ * @author 韩福成
+ * @date 2025-11-21
+ */
+@Service
+public class PerformanceEvaluationServiceImpl implements IPerformanceEvaluationService {
+    @Autowired
+    private PerformanceEvaluationMapper performanceEvaluationMapper;
+
+    /**
+     * 查询考核评价
+     *
+     * @param id 考核评价主键
+     * @return 考核评价
+     */
+    @Override
+    public PerformanceEvaluation selectPerformanceEvaluationById(Long id) {
+        PerformanceEvaluation performanceEvaluation = performanceEvaluationMapper.selectPerformanceEvaluationById(id);
+        StringBuilder newDiles = new StringBuilder();
+        if (StringUtils.isNotEmpty(performanceEvaluation.getFileUrl())) {
+            String fileurl = SpringUtils.getBean(RemoteConfigService.class).remotegetConfigKey(DOWNLOAD_URL).getData();
+            String filename = performanceEvaluation.getFileName(); //新建 Microsoft Excel 工作表 (2).xlsx
+            String url = performanceEvaluation.getFileUrl().substring(performanceEvaluation.getFileUrl().indexOf("group1")); //group1/M00/00/84/wKgKEGawNfGAW7bwAAAxRySSUAM25.xlsx
+            String group = url.substring(0, url.indexOf('/')); //group1
+            newDiles.append(fileurl).append("Download?fileName=").append(filename).append("&&group=").append(group).append("&&path=").append(url.substring(url.indexOf('/') + 1)).append("+").append(filename).append(",");
+            if (newDiles.length() > 0) {
+                newDiles.deleteCharAt(newDiles.length() - 1);
+            }
+            performanceEvaluation.setFileUrl(newDiles.toString());
+        }
+        return performanceEvaluation;
+    }
+
+    /**
+     * 查询考核评价列表
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 考核评价
+     */
+    @Override
+    public List<PerformanceEvaluation> selectPerformanceEvaluationList(PerformanceEvaluation performanceEvaluation) {
+        return performanceEvaluationMapper.selectPerformanceEvaluationList(performanceEvaluation);
+    }
+
+    /**
+     * 新增考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    @Override
+    public int insertPerformanceEvaluation(PerformanceEvaluation performanceEvaluation) {
+        performanceEvaluation.setCreateTime(DateUtils.getNowDate());
+        performanceEvaluation.setCreateBy(SecurityUtils.getUserId().toString());
+        performanceEvaluation.setCreateName(SecurityUtils.getLoginUser().getSysUser().getNickName());
+        extracted(performanceEvaluation);
+        return performanceEvaluationMapper.insertPerformanceEvaluation(performanceEvaluation);
+    }
+
+    /**
+     * 修改考核评价
+     *
+     * @param performanceEvaluation 考核评价
+     * @return 结果
+     */
+    @Override
+    public int updatePerformanceEvaluation(PerformanceEvaluation performanceEvaluation) {
+        performanceEvaluation.setUpdateTime(DateUtils.getNowDate());
+        performanceEvaluation.setUpdateBy(SecurityUtils.getUserId());
+        performanceEvaluation.setUpdateName( SecurityUtils.getLoginUser().getSysUser().getNickName());
+        extracted(performanceEvaluation);
+        return performanceEvaluationMapper.updatePerformanceEvaluation(performanceEvaluation);
+    }
+
+    private void extracted(PerformanceEvaluation performanceEvaluation) {
+        if (StringUtils.isNotEmpty(performanceEvaluation.getFileUrl())) {
+            String attachPath = performanceEvaluation.getFileUrl();
+            // 如果路径以 "http" 开头
+            if (attachPath.startsWith("http")) {
+                // 检查路径中是否包含 "Download"
+                if (attachPath.contains("Download")) {
+                    // 找到 "group=" 的位置
+                    int i1 = attachPath.indexOf("group=");
+                    // 将路径中的 "&&path=" 替换为 "/"
+                    attachPath = attachPath.replace("&&path=", "/");
+                    // 从 "group=" 之后的位置截取子字符串,并将其添加到 pathList 中
+                    attachPath = attachPath.substring(i1 + 6);
+                    performanceEvaluation.setFileUrl(attachPath);
+                } else {
+                    // 找到路径中第一个 '/' 的位置
+                    int i1 = attachPath.indexOf('/'); //5
+                    // 找到路径中第二个 '/' 的位置
+                    int i2 = attachPath.indexOf('/', i1 + 1); //
+                    // 找到路径中第三个 '/' 的位置
+                    int i3 = attachPath.indexOf('/', i2 + 1);
+                    performanceEvaluation.setFileUrl(attachPath.substring(i3 + 1));
+                }
+            }
+        }
+    }
+
+    /**
+     * 批量删除考核评价
+     *
+     * @param ids 需要删除的考核评价主键
+     * @return 结果
+     */
+    @Override
+    public int deletePerformanceEvaluationByIds(Long[] ids) {
+        return performanceEvaluationMapper.deletePerformanceEvaluationByIds(ids);
+    }
+
+    /**
+     * 删除考核评价信息
+     *
+     * @param id 考核评价主键
+     * @return 结果
+     */
+    @Override
+    public int deletePerformanceEvaluationById(Long id) {
+        return performanceEvaluationMapper.deletePerformanceEvaluationById(id);
+    }
+}

+ 8 - 0
src/main/java/com/sooka/sponest/construction/gas/domain/GasInspectionTaskRecord.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.web.domain.BaseEntity;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
@@ -65,8 +66,15 @@ public class GasInspectionTaskRecord extends BaseEntity {
     @ApiModelProperty(value = "任务轨迹", required = false)
     private String taskTrajectory;
 
+    //巡检距离
+    private BigDecimal distance;
+
+    //任务id
     private List<Long> taskIdList;
 
+    //记录id
+    private List<Long> recordList;
+
     private String taskName;
 
 }

+ 5 - 0
src/main/java/com/sooka/sponest/construction/gas/domain/GasStation.java

@@ -92,6 +92,11 @@ public class GasStation extends BaseBusinessEntity {
     private String deptName;
 
     /**
+     * 所属部门
+     */
+    private String manufacturingDate;
+
+    /**
      * 绑定的设备列表
      */
     private List<GasDeviceBaseInfoData> devices;

+ 4 - 0
src/main/java/com/sooka/sponest/construction/gas/mapper/GasDeviceBaseInfoDataMapper.java

@@ -1,9 +1,11 @@
 package com.sooka.sponest.construction.gas.mapper;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.gas.domain.GasDeviceBaseInfoData;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -73,4 +75,6 @@ public interface GasDeviceBaseInfoDataMapper {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/gas/mapper/GasInspectionTaskRecordMapper.java

@@ -4,6 +4,7 @@ package com.sooka.sponest.construction.gas.mapper;
 import com.sooka.sponest.construction.gas.domain.GasInspectionTaskRecord;
 import com.sooka.sponest.construction.gas.domain.GasTaskPipe;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -84,4 +85,6 @@ public interface GasInspectionTaskRecordMapper {
      * @date 2025/9/12 上午11:16
      */
     public List<GasTaskPipe> getGasPipeByTaskIds(String taskIdList);
+    // 计算本次巡检距离
+    public BigDecimal getDistance(Long recordId);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/gas/service/IGasDeviceBaseInfoDataService.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.gas.service;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.gas.domain.GasDeviceBaseInfoData;
@@ -72,4 +73,6 @@ public interface IGasDeviceBaseInfoDataService {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate);
 }

+ 6 - 0
src/main/java/com/sooka/sponest/construction/gas/service/impl/GasDeviceBaseInfoDataServiceImpl.java

@@ -2,6 +2,7 @@ package com.sooka.sponest.construction.gas.service.impl;
 
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.gas.domain.GasDeviceBaseInfoData;
@@ -111,4 +112,9 @@ public class GasDeviceBaseInfoDataServiceImpl extends BaseServiceImpl implements
         return gasDeviceBaseInfoDataMapper.getDeviceType();
     }
 
+    @Override
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate) {
+        return gasDeviceBaseInfoDataMapper.getDeviceEventAlarmList(startDate, endDate);
+    }
+
 }

+ 21 - 7
src/main/java/com/sooka/sponest/construction/gas/service/impl/GasPipeInspectionTaskServiceImpl.java

@@ -8,10 +8,14 @@ import com.sooka.sponest.base.service.impl.BaseServiceImpl;
 import com.sooka.sponest.construction.gas.domain.*;
 import com.sooka.sponest.construction.gas.mapper.*;
 import com.sooka.sponest.construction.gas.service.IGasPipeInspectionTaskService;
+import com.sooka.sponest.construction.supervisoryPlatform.domain.InspectionMileage;
+import com.sooka.sponest.construction.supervisoryPlatform.mapper.InspectionMileageMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -171,7 +175,7 @@ public class GasPipeInspectionTaskServiceImpl extends BaseServiceImpl implements
      */
     @Override
     public List<Long> startRecord(GasInspectionTaskRecord gasInspectionTaskRecord) {
-        List<Long> taskIdList = new ArrayList<>();
+        List<Long> recordList = new ArrayList<>();
         for (Long taskId : gasInspectionTaskRecord.getTaskIdList()) {
             //先结束当前用户在当前任务中所有未结束的巡检记录记录
             GasInspectionTaskRecord record = new GasInspectionTaskRecord();
@@ -188,12 +192,14 @@ public class GasPipeInspectionTaskServiceImpl extends BaseServiceImpl implements
             gasInspectionTaskRecord.setUserName(SecurityUtils.getLoginUser().getSysUser().getNickName());
             //新增巡检任务记录
             gasInspectionTaskRecordMapper.insertGasInspectionTaskRecord(gasInspectionTaskRecord);
-            taskIdList.add(gasInspectionTaskRecord.getId());
+            recordList.add(gasInspectionTaskRecord.getId());
         }
 
-        return taskIdList;
+        return recordList;
     }
 
+    @Resource
+    private InspectionMileageMapper inspectionMileageMapper;
     /*
      * 结束巡检
      *
@@ -202,12 +208,20 @@ public class GasPipeInspectionTaskServiceImpl extends BaseServiceImpl implements
      */
     @Override
     public int finishRecord(GasInspectionTaskRecord gasInspectionTaskRecord) {
-        for (Long taskId : gasInspectionTaskRecord.getTaskIdList()) {
-            gasInspectionTaskRecord.setUserId(SecurityUtils.getLoginUser().getSysUser().getUserId());
-            gasInspectionTaskRecord.setTaskId(taskId);
+        for (Long recordId : gasInspectionTaskRecord.getRecordList()) {
+            BigDecimal distance = gasInspectionTaskRecordMapper.getDistance(recordId);
+            InspectionMileage mileage = new InspectionMileage();
+            mileage.setInspectionId(5L);
+            InspectionMileage mileage1 = inspectionMileageMapper.selectInspectionMileageList(mileage).get(0);
+            mileage1.setMileage(mileage1.getMileage().add(distance));
+            inspectionMileageMapper.updateInspectionMileage(mileage1);
+
+            gasInspectionTaskRecord.setId(recordId);
             gasInspectionTaskRecord.setStatus("1");
             gasInspectionTaskRecord.setEndTime(DateUtils.getNowDate());
-            gasInspectionTaskRecordMapper.updateGasInspectionTaskRecordByUserIdAndTaskId(gasInspectionTaskRecord);
+            gasInspectionTaskRecord.setDistance(distance);
+            gasInspectionTaskRecordMapper.updateGasInspectionTaskRecord(gasInspectionTaskRecord);
+
         }
         return 1;
     }

+ 8 - 0
src/main/java/com/sooka/sponest/construction/heating/domain/HeatingInspectionTaskRecord.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.web.domain.BaseEntity;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
@@ -66,8 +67,15 @@ public class HeatingInspectionTaskRecord extends BaseEntity {
     @ApiModelProperty(value = "任务轨迹", required = false)
     private String taskTrajectory;
 
+    //巡检距离
+    private BigDecimal distance;
+
+    //任务id
     private List<Long> taskIdList;
 
+    //记录id
+    private List<Long> recordList;
+
     private String taskName;
 
 }

+ 2 - 0
src/main/java/com/sooka/sponest/construction/heating/domain/HeatingMaintenanceReport.java

@@ -51,6 +51,8 @@ public class HeatingMaintenanceReport extends BaseBusinessEntity {
      */
     @Excel(name = "附件")
     private String reportUrl;
+
+    private String fileName;
     private Long deptId;
     private String deptName;
 

+ 3 - 0
src/main/java/com/sooka/sponest/construction/heating/mapper/HeatingDeviceMapper.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.heating.mapper;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.heating.domain.HeatingDevice;
@@ -85,4 +86,6 @@ public interface HeatingDeviceMapper {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(@Param("startDate") String startDate, @Param("endDate") String endDate);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/heating/mapper/HeatingInspectionTaskRecordMapper.java

@@ -4,6 +4,7 @@ package com.sooka.sponest.construction.heating.mapper;
 import com.sooka.sponest.construction.heating.domain.HeatingInspectionTaskRecord;
 import com.sooka.sponest.construction.heating.domain.HeatingTaskPipe;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -86,4 +87,6 @@ public interface HeatingInspectionTaskRecordMapper {
      * @date 2025/9/12 上午11:16
      */
     public List<HeatingTaskPipe> getHeatingPipeByTaskIds(String taskIdList);
+    // 计算本次巡检距离
+    public BigDecimal getDistance(Long recordId);
 }

+ 3 - 0
src/main/java/com/sooka/sponest/construction/heating/service/IHeatingDeviceService.java

@@ -1,5 +1,6 @@
 package com.sooka.sponest.construction.heating.service;
 
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.heating.domain.HeatingDevice;
@@ -76,4 +77,6 @@ public interface IHeatingDeviceService {
     public List<DeviceSummaryVO> getDeviceSummary();
 
     public List<DeviceTypeVO> getDeviceType();
+
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate);
 }

+ 7 - 0
src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingDeviceServiceImpl.java

@@ -2,6 +2,7 @@ package com.sooka.sponest.construction.heating.service.impl;
 
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
+import com.sooka.sponest.construction.api.vo.DeviceEventAlarmVO;
 import com.sooka.sponest.construction.api.vo.DeviceSummaryVO;
 import com.sooka.sponest.construction.api.vo.DeviceTypeVO;
 import com.sooka.sponest.construction.heating.domain.HeatingDevice;
@@ -13,6 +14,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -120,4 +122,9 @@ public class HeatingDeviceServiceImpl extends BaseServiceImpl implements IHeatin
     public List<DeviceTypeVO> getDeviceType() {
         return heatingDeviceMapper.getDeviceType();
     }
+
+    @Override
+    public List<DeviceEventAlarmVO> getDeviceEventAlarmList(String startDate, String endDate) {
+        return heatingDeviceMapper.getDeviceEventAlarmList(startDate, endDate);
+    }
 }

+ 42 - 5
src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingMaintenanceReportServiceImpl.java

@@ -1,6 +1,9 @@
 package com.sooka.sponest.construction.heating.service.impl;
 
+import com.ruoyi.common.core.utils.SpringUtils;
+import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
+import com.ruoyi.system.api.RemoteConfigService;
 import com.sooka.sponest.base.service.impl.BaseServiceImpl;
 import com.sooka.sponest.construction.heating.domain.HeatingMaintenanceReport;
 import com.sooka.sponest.construction.heating.mapper.HeatingMaintenanceReportMapper;
@@ -11,6 +14,8 @@ import org.springframework.stereotype.Service;
 
 import java.util.List;
 
+import static com.sooka.sponest.utils.DataConstants.DOWNLOAD_URL;
+
 /**
  * 供热维护报告Service业务层处理
  *
@@ -32,7 +37,21 @@ public class HeatingMaintenanceReportServiceImpl extends BaseServiceImpl impleme
      */
     @Override
     public HeatingMaintenanceReport selectHeatingMaintenanceReportById(Long id) {
-        return heatingMaintenanceReportMapper.selectHeatingMaintenanceReportById(id);
+        HeatingMaintenanceReport heatingMaintenanceReport = heatingMaintenanceReportMapper.selectHeatingMaintenanceReportById(id);
+        if (StringUtils.isNotEmpty(heatingMaintenanceReport.getReportUrl())) {
+            StringBuilder newDiles = new StringBuilder();
+            String fileurl = SpringUtils.getBean(RemoteConfigService.class).remotegetConfigKey(DOWNLOAD_URL).getData();
+            String filename = heatingMaintenanceReport.getFileName(); //新建 Microsoft Excel 工作表 (2).xlsx
+            String url = heatingMaintenanceReport.getReportUrl().substring(heatingMaintenanceReport.getReportUrl().indexOf("group1")); //group1/M00/00/84/wKgKEGawNfGAW7bwAAAxRySSUAM25.xlsx
+            String group = url.substring(0, url.indexOf('/')); //group1
+            newDiles.append(fileurl + "Download?fileName=" + filename + "&&group=" + group + "&&path=" + url.substring(url.indexOf('/') + 1) + "+" + filename + ",");
+            if (newDiles.length() > 0) {
+                newDiles.deleteCharAt(newDiles.length() - 1);
+            }
+            heatingMaintenanceReport.setReportUrl(newDiles.toString());
+        }
+
+        return heatingMaintenanceReport;
     }
 
     /**
@@ -70,10 +89,28 @@ public class HeatingMaintenanceReportServiceImpl extends BaseServiceImpl impleme
      * 附件图片前缀lc
      */
     private void removeUrlPrefix(HeatingMaintenanceReport heatingMaintenanceReport) {
-        if (heatingMaintenanceReport.getReportUrl() != null && !heatingMaintenanceReport.getReportUrl().isEmpty()) {
-            String url = heatingMaintenanceReport.getReportUrl();
-            if (url.contains("group")) {
-                heatingMaintenanceReport.setReportUrl(url.substring(url.indexOf("group")));
+        String url = heatingMaintenanceReport.getReportUrl();
+        if (StringUtils.isNotEmpty(url)) {
+            // 如果路径以 "http" 开头
+            if (url.startsWith("http")) {
+                // 检查路径中是否包含 "Download"
+                if (url.contains("Download")) {
+                    // 找到 "group=" 的位置
+                    int i1 = url.indexOf("group=");
+                    // 将路径中的 "&&path=" 替换为 "/"
+                    url = url.replace("&&path=", "/");
+                    // 从 "group=" 之后的位置截取子字符串,并将其添加到 pathList 中
+                    url = url.substring(i1 + 6);
+                    heatingMaintenanceReport.setReportUrl(url);
+                } else {
+                    // 找到路径中第一个 '/' 的位置
+                    int i1 = url.indexOf('/'); //5
+                    // 找到路径中第二个 '/' 的位置
+                    int i2 = url.indexOf('/', i1 + 1); //
+                    // 找到路径中第三个 '/' 的位置
+                    int i3 = url.indexOf('/', i2 + 1);
+                    heatingMaintenanceReport.setReportUrl(url.substring(i3 + 1));
+                }
             }
         }
     }

+ 21 - 7
src/main/java/com/sooka/sponest/construction/heating/service/impl/HeatingPipeInspectionTaskServiceImpl.java

@@ -8,10 +8,14 @@ import com.sooka.sponest.base.service.impl.BaseServiceImpl;
 import com.sooka.sponest.construction.heating.domain.*;
 import com.sooka.sponest.construction.heating.mapper.*;
 import com.sooka.sponest.construction.heating.service.IHeatingPipeInspectionTaskService;
+import com.sooka.sponest.construction.supervisoryPlatform.domain.InspectionMileage;
+import com.sooka.sponest.construction.supervisoryPlatform.mapper.InspectionMileageMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -171,7 +175,7 @@ public class HeatingPipeInspectionTaskServiceImpl extends BaseServiceImpl implem
      */
     @Override
     public List<Long> startRecord(HeatingInspectionTaskRecord heatingInspectionTaskRecord) {
-        List<Long> taskIdList = new ArrayList<>();
+        List<Long> recordList = new ArrayList<>();
         for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
             //先结束当前用户在当前任务中所有未结束的巡检记录记录
             HeatingInspectionTaskRecord record = new HeatingInspectionTaskRecord();
@@ -188,12 +192,14 @@ public class HeatingPipeInspectionTaskServiceImpl extends BaseServiceImpl implem
             heatingInspectionTaskRecord.setUserName(SecurityUtils.getLoginUser().getSysUser().getNickName());
             //新增巡检任务记录
             heatingInspectionTaskRecordMapper.insertHeatingInspectionTaskRecord(heatingInspectionTaskRecord);
-            taskIdList.add(heatingInspectionTaskRecord.getId());
+            recordList.add(heatingInspectionTaskRecord.getId());
         }
 
-        return taskIdList;
+        return recordList;
     }
 
+    @Resource
+    private InspectionMileageMapper inspectionMileageMapper;
     /*
      * 结束巡检
      *
@@ -202,12 +208,20 @@ public class HeatingPipeInspectionTaskServiceImpl extends BaseServiceImpl implem
      */
     @Override
     public int finishRecord(HeatingInspectionTaskRecord heatingInspectionTaskRecord) {
-        for (Long taskId : heatingInspectionTaskRecord.getTaskIdList()) {
-            heatingInspectionTaskRecord.setUserId(SecurityUtils.getLoginUser().getSysUser().getUserId());
-            heatingInspectionTaskRecord.setTaskId(taskId);
+        for (Long recordId : heatingInspectionTaskRecord.getRecordList()) {
+            BigDecimal distance = heatingInspectionTaskRecordMapper.getDistance(recordId);
+            InspectionMileage mileage = new InspectionMileage();
+            mileage.setInspectionId(1L);
+            InspectionMileage mileage1 = inspectionMileageMapper.selectInspectionMileageList(mileage).get(0);
+            mileage1.setMileage(mileage1.getMileage().add(distance));
+            inspectionMileageMapper.updateInspectionMileage(mileage1);
+
+            heatingInspectionTaskRecord.setTaskId(recordId);
             heatingInspectionTaskRecord.setStatus("1");
             heatingInspectionTaskRecord.setEndTime(DateUtils.getNowDate());
-            heatingInspectionTaskRecordMapper.updateHeatingInspectionTaskRecordByUserIdAndTaskId(heatingInspectionTaskRecord);
+            heatingInspectionTaskRecord.setDistance(distance);
+            heatingInspectionTaskRecordMapper.updateHeatingInspectionTaskRecord(heatingInspectionTaskRecord);
+
         }
         return 1;
     }

+ 128 - 0
src/main/java/com/sooka/sponest/construction/operateSystem/controller/OperateController.java

@@ -0,0 +1,128 @@
+package com.sooka.sponest.construction.operateSystem.controller;
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.sooka.sponest.construction.operateSystem.domain.Operate;
+import com.sooka.sponest.construction.operateSystem.service.IOperateService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+/*
+ * 运营体系
+ *
+ * @author 韩福成
+ * @date 2025/11/19 上午10:24
+ */
+@RestController
+@RequestMapping("/operate")
+public class OperateController extends BaseController {
+    @Autowired
+    private IOperateService operateService;
+
+    /*
+     * 通知公告
+     *
+     * @author 韩福成
+     * @date 2025/11/19 上午10:30
+     */
+    @GetMapping("/getNotice")
+    public AjaxResult getNotice(Operate operate) {
+        return AjaxResult.success(operateService.getNotice(operate));
+    }
+
+    /*
+    * 值班管理
+    *
+    * @author 韩福成
+    * @date 2025/11/19 下午2:02
+    */
+    @GetMapping("/getDutyManagement")
+    public AjaxResult getDutyManagement(Operate operate) {
+        return AjaxResult.success(operateService.getDutyManagement(operate));
+    }
+
+    /*
+    * 任务列表
+    *
+    * @author 韩福成
+    * @date 2025/11/19 下午3:01
+    */
+    @GetMapping("/getTaskList")
+    public AjaxResult getTaskList(Operate operate) {
+        return AjaxResult.success(operateService.getTaskList(operate));
+    }
+
+    /*
+    * 维护报告
+    *
+    * @author 韩福成
+    * @date 2025/11/19 下午3:31
+    */
+    @GetMapping("/getMaintenanceReport")
+    public AjaxResult getMaintenanceReport(Operate operate) {
+        return AjaxResult.success(operateService.getMaintenanceReport(operate));
+    }
+
+    /*
+    * 人员列表
+    *
+    * @author 韩福成
+    * @date 2025/11/19 下午3:43
+    */
+    @GetMapping("/getUserList")
+    public AjaxResult getUserList(Operate operate) {
+        return AjaxResult.success(operateService.getUserList(operate));
+    }
+
+    /*
+    * 考核评价
+    *
+    * @author 韩福成
+    * @date 2025/11/21 下午4:01
+    */
+    @GetMapping("/getPerformanceList")
+    public AjaxResult getPerformanceList(Operate operate) {
+        return AjaxResult.success(operateService.getPerformanceList(operate));
+    }
+
+    /*
+    * 驾驶舱 - 风险分析统计
+    *
+    * @author 韩福成
+    * @date 2025/11/25 上午9:32
+    */
+    @GetMapping("/getRiskRegister")
+    public AjaxResult getRiskRegister(Operate operate) {
+        return AjaxResult.success(operateService.getRiskRegister(operate));
+    }
+
+    /*
+    * 驾驶舱 - 工地监管列表
+    *
+    * @author 韩福成
+    * @date 2025/11/25 下午5:05
+    */
+    @GetMapping("/getSupervisionList")
+    public TableDataInfo getSupervisionList(Operate operate) {
+        startPage();
+        List<Map<String, Object>> supervision = operateService.getSupervisionList(operate);
+        return getDataTable(supervision);
+    }
+
+    /*
+    * 驾驶舱 - 工地监管详情
+    *
+    * @author 韩福成
+    * @date 2025/11/25 下午6:03
+    */
+    @GetMapping("/getSupervisionDetails")
+    public AjaxResult getSupervisionDetails(Operate operate) {
+        return AjaxResult.success(operateService.getSupervisionDetails(operate));
+    }
+}

+ 33 - 0
src/main/java/com/sooka/sponest/construction/operateSystem/domain/Operate.java

@@ -0,0 +1,33 @@
+package com.sooka.sponest.construction.operateSystem.domain;
+
+import com.sooka.sponest.base.domain.BaseBusinessEntity;
+import lombok.Data;
+
+import java.util.List;
+
+/*
+ * 运营体系
+ *
+ * @author 韩福成
+ * @date 2025/11/19 上午10:43
+ */
+@Data
+public class Operate extends BaseBusinessEntity {
+
+    //0:全部;1:热力;2:排水;3:桥梁;4:管廊;5:燃气;6:供水
+    private String type;
+
+    private List<String> deptIds;
+
+    private String deptId;
+
+    private String name;
+
+    private String date;
+
+    //风险等级
+    private String level;
+
+    //工地id
+    private String constructionId;
+}

+ 0 - 0
src/main/java/com/sooka/sponest/construction/operateSystem/mapper/OperateMapper.java


部分文件因为文件数量过多而无法显示