Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

wangxx недель назад: 4
Родитель
Сommit
89f5176eb8
19 измененных файлов с 370 добавлено и 161 удалено
  1. 4 4
      airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerSeizureStatsController.java
  2. 1 3
      airport-admin/src/main/java/com/sundot/airport/web/controller/score/ScoreDimensionController.java
  3. 70 51
      airport-common/src/main/java/com/sundot/airport/common/utils/DateUtils.java
  4. 2 2
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/OperationStationHourlyThroughput.java
  5. 4 0
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/AreaFlowVO.java
  6. 16 2
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/LaneThroughputResVO.java
  7. 2 2
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/SeizeCategoryQuantityVO.java
  8. 6 1
      airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/StationHourlyThroughputGroupResVO.java
  9. 2 2
      airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerSeizureStatsMapper.java
  10. 2 2
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerSeizureStatsService.java
  11. 3 3
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerSeizureStatsServiceImpl.java
  12. 56 5
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/OperationLanePeakThroughputServiceImpl.java
  13. 153 34
      airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/OperationStationHourlyThroughputServiceImpl.java
  14. 13 11
      airport-ledger/src/main/resources/mapper/ledger/LedgerSeizureStatsMapper.xml
  15. 3 1
      airport-ledger/src/main/resources/mapper/ledger/LedgerUnsafeEventMapper.xml
  16. 9 27
      airport-ledger/src/main/resources/mapper/ledger/OperationLanePeakThroughputMapper.xml
  17. 21 8
      airport-ledger/src/main/resources/mapper/ledger/OperationStationHourlyThroughputMapper.xml
  18. 1 1
      airport-system/src/main/java/com/sundot/airport/system/mapper/BasePositionMapper.java
  19. 2 2
      sql/station_hourly_throughput.sql

+ 4 - 4
airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerSeizureStatsController.java

@@ -104,13 +104,13 @@ public class LedgerSeizureStatsController extends BaseController {
104
      *
104
      *
105
      * @param countQueryReq 查询参数
105
      * @param countQueryReq 查询参数
106
      * @return AjaxResult
106
      * @return AjaxResult
107
-     * @method countSeizureInfoItem
107
+     * @method countSeizeSubjectItemQuantity
108
      * @author PanHu Sun
108
      * @author PanHu Sun
109
      * @date 2026/5/20 13:32
109
      * @date 2026/5/20 13:32
110
      */
110
      */
111
-    @PostMapping("/countSeizeSubjectCategoryQuantity")
112
-    public AjaxResult countSeizeSubjectCategoryQuantity(@RequestBody CountQueryReqVO countQueryReq) {
113
-        List<SeizeCategoryQuantityVO> seizeCategoryQuantityList = service.countSeizeSubjectCategoryQuantity(countQueryReq);
111
+    @PostMapping("/countSeizeSubjectItemQuantity")
112
+    public AjaxResult countSeizeSubjectItemQuantity(@RequestBody CountQueryReqVO countQueryReq) {
113
+        List<SeizeCategoryQuantityVO> seizeCategoryQuantityList = service.countSeizeSubjectItemQuantity(countQueryReq);
114
         return AjaxResult.success(seizeCategoryQuantityList);
114
         return AjaxResult.success(seizeCategoryQuantityList);
115
     }
115
     }
116
 
116
 

+ 1 - 3
airport-admin/src/main/java/com/sundot/airport/web/controller/score/ScoreDimensionController.java

@@ -37,9 +37,7 @@ public class ScoreDimensionController extends BaseController {
37
     /** 不分页列表,用于前端下拉选择 */
37
     /** 不分页列表,用于前端下拉选择 */
38
     @PreAuthorize("@ss.hasPermi('score:dimension:list')")
38
     @PreAuthorize("@ss.hasPermi('score:dimension:list')")
39
     @GetMapping("/all")
39
     @GetMapping("/all")
40
-    public AjaxResult all() {
41
-        ScoreDimension query = new ScoreDimension();
42
-        query.setStatus("0");
40
+    public AjaxResult all(ScoreDimension query) {
43
         return AjaxResult.success(service.selectList(query));
41
         return AjaxResult.success(service.selectList(query));
44
     }
42
     }
45
 
43
 

+ 70 - 51
airport-common/src/main/java/com/sundot/airport/common/utils/DateUtils.java

@@ -8,16 +8,20 @@ import java.time.LocalDateTime;
8
 import java.time.LocalTime;
8
 import java.time.LocalTime;
9
 import java.time.ZoneId;
9
 import java.time.ZoneId;
10
 import java.time.ZonedDateTime;
10
 import java.time.ZonedDateTime;
11
+import java.util.Calendar;
11
 import java.util.Date;
12
 import java.util.Date;
13
+import java.util.List;
14
+import java.util.Objects;
15
+
16
+import com.google.common.collect.Lists;
12
 import org.apache.commons.lang3.time.DateFormatUtils;
17
 import org.apache.commons.lang3.time.DateFormatUtils;
13
 
18
 
14
 /**
19
 /**
15
  * 时间工具类
20
  * 时间工具类
16
- * 
21
+ *
17
  * @author ruoyi
22
  * @author ruoyi
18
  */
23
  */
19
-public class DateUtils extends org.apache.commons.lang3.time.DateUtils
20
-{
24
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
21
     public static String YYYY = "yyyy";
25
     public static String YYYY = "yyyy";
22
 
26
 
23
     public static String YYYY_MM = "yyyy-MM";
27
     public static String YYYY_MM = "yyyy-MM";
@@ -29,63 +33,52 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
29
     public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
33
     public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
30
 
34
 
31
     private static String[] parsePatterns = {
35
     private static String[] parsePatterns = {
32
-            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
36
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
33
             "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
37
             "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
34
             "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
38
             "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
35
 
39
 
36
     /**
40
     /**
37
      * 获取当前Date型日期
41
      * 获取当前Date型日期
38
-     * 
42
+     *
39
      * @return Date() 当前日期
43
      * @return Date() 当前日期
40
      */
44
      */
41
-    public static Date getNowDate()
42
-    {
45
+    public static Date getNowDate() {
43
         return new Date();
46
         return new Date();
44
     }
47
     }
45
 
48
 
46
     /**
49
     /**
47
      * 获取当前日期, 默认格式为yyyy-MM-dd
50
      * 获取当前日期, 默认格式为yyyy-MM-dd
48
-     * 
51
+     *
49
      * @return String
52
      * @return String
50
      */
53
      */
51
-    public static String getDate()
52
-    {
54
+    public static String getDate() {
53
         return dateTimeNow(YYYY_MM_DD);
55
         return dateTimeNow(YYYY_MM_DD);
54
     }
56
     }
55
 
57
 
56
-    public static final String getTime()
57
-    {
58
+    public static final String getTime() {
58
         return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
59
         return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
59
     }
60
     }
60
 
61
 
61
-    public static final String dateTimeNow()
62
-    {
62
+    public static final String dateTimeNow() {
63
         return dateTimeNow(YYYYMMDDHHMMSS);
63
         return dateTimeNow(YYYYMMDDHHMMSS);
64
     }
64
     }
65
 
65
 
66
-    public static final String dateTimeNow(final String format)
67
-    {
66
+    public static final String dateTimeNow(final String format) {
68
         return parseDateToStr(format, new Date());
67
         return parseDateToStr(format, new Date());
69
     }
68
     }
70
 
69
 
71
-    public static final String dateTime(final Date date)
72
-    {
70
+    public static final String dateTime(final Date date) {
73
         return parseDateToStr(YYYY_MM_DD, date);
71
         return parseDateToStr(YYYY_MM_DD, date);
74
     }
72
     }
75
 
73
 
76
-    public static final String parseDateToStr(final String format, final Date date)
77
-    {
74
+    public static final String parseDateToStr(final String format, final Date date) {
78
         return new SimpleDateFormat(format).format(date);
75
         return new SimpleDateFormat(format).format(date);
79
     }
76
     }
80
 
77
 
81
-    public static final Date dateTime(final String format, final String ts)
82
-    {
83
-        try
84
-        {
78
+    public static final Date dateTime(final String format, final String ts) {
79
+        try {
85
             return new SimpleDateFormat(format).parse(ts);
80
             return new SimpleDateFormat(format).parse(ts);
86
-        }
87
-        catch (ParseException e)
88
-        {
81
+        } catch (ParseException e) {
89
             throw new RuntimeException(e);
82
             throw new RuntimeException(e);
90
         }
83
         }
91
     }
84
     }
@@ -93,8 +86,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
93
     /**
86
     /**
94
      * 日期路径 即年/月/日 如2018/08/08
87
      * 日期路径 即年/月/日 如2018/08/08
95
      */
88
      */
96
-    public static final String datePath()
97
-    {
89
+    public static final String datePath() {
98
         Date now = new Date();
90
         Date now = new Date();
99
         return DateFormatUtils.format(now, "yyyy/MM/dd");
91
         return DateFormatUtils.format(now, "yyyy/MM/dd");
100
     }
92
     }
@@ -102,8 +94,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
102
     /**
94
     /**
103
      * 日期路径 即年/月/日 如20180808
95
      * 日期路径 即年/月/日 如20180808
104
      */
96
      */
105
-    public static final String dateTime()
106
-    {
97
+    public static final String dateTime() {
107
         Date now = new Date();
98
         Date now = new Date();
108
         return DateFormatUtils.format(now, "yyyyMMdd");
99
         return DateFormatUtils.format(now, "yyyyMMdd");
109
     }
100
     }
@@ -111,18 +102,13 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
111
     /**
102
     /**
112
      * 日期型字符串转化为日期 格式
103
      * 日期型字符串转化为日期 格式
113
      */
104
      */
114
-    public static Date parseDate(Object str)
115
-    {
116
-        if (str == null)
117
-        {
105
+    public static Date parseDate(Object str) {
106
+        if (str == null) {
118
             return null;
107
             return null;
119
         }
108
         }
120
-        try
121
-        {
109
+        try {
122
             return parseDate(str.toString(), parsePatterns);
110
             return parseDate(str.toString(), parsePatterns);
123
-        }
124
-        catch (ParseException e)
125
-        {
111
+        } catch (ParseException e) {
126
             return null;
112
             return null;
127
         }
113
         }
128
     }
114
     }
@@ -130,8 +116,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
130
     /**
116
     /**
131
      * 获取服务器启动时间
117
      * 获取服务器启动时间
132
      */
118
      */
133
-    public static Date getServerStartDate()
134
-    {
119
+    public static Date getServerStartDate() {
135
         long time = ManagementFactory.getRuntimeMXBean().getStartTime();
120
         long time = ManagementFactory.getRuntimeMXBean().getStartTime();
136
         return new Date(time);
121
         return new Date(time);
137
     }
122
     }
@@ -139,20 +124,18 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
139
     /**
124
     /**
140
      * 计算相差天数
125
      * 计算相差天数
141
      */
126
      */
142
-    public static int differentDaysByMillisecond(Date date1, Date date2)
143
-    {
127
+    public static int differentDaysByMillisecond(Date date1, Date date2) {
144
         return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
128
         return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
145
     }
129
     }
146
 
130
 
147
     /**
131
     /**
148
      * 计算时间差
132
      * 计算时间差
149
      *
133
      *
150
-     * @param endDate 最后时间
134
+     * @param endDate   最后时间
151
      * @param startTime 开始时间
135
      * @param startTime 开始时间
152
      * @return 时间差(天/小时/分钟)
136
      * @return 时间差(天/小时/分钟)
153
      */
137
      */
154
-    public static String timeDistance(Date endDate, Date startTime)
155
-    {
138
+    public static String timeDistance(Date endDate, Date startTime) {
156
         long nd = 1000 * 24 * 60 * 60;
139
         long nd = 1000 * 24 * 60 * 60;
157
         long nh = 1000 * 60 * 60;
140
         long nh = 1000 * 60 * 60;
158
         long nm = 1000 * 60;
141
         long nm = 1000 * 60;
@@ -173,8 +156,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
173
     /**
156
     /**
174
      * 增加 LocalDateTime ==> Date
157
      * 增加 LocalDateTime ==> Date
175
      */
158
      */
176
-    public static Date toDate(LocalDateTime temporalAccessor)
177
-    {
159
+    public static Date toDate(LocalDateTime temporalAccessor) {
178
         ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
160
         ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
179
         return Date.from(zdt.toInstant());
161
         return Date.from(zdt.toInstant());
180
     }
162
     }
@@ -182,10 +164,47 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
182
     /**
164
     /**
183
      * 增加 LocalDate ==> Date
165
      * 增加 LocalDate ==> Date
184
      */
166
      */
185
-    public static Date toDate(LocalDate temporalAccessor)
186
-    {
167
+    public static Date toDate(LocalDate temporalAccessor) {
187
         LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
168
         LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
188
         ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
169
         ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
189
         return Date.from(zdt.toInstant());
170
         return Date.from(zdt.toInstant());
190
     }
171
     }
172
+
173
+    /**
174
+     * 生成近30天的日期列表(包含今天)
175
+     */
176
+    public static List<Date> generateLast30Days() {
177
+        List<Date> dates = Lists.newArrayList();
178
+        Calendar calendar = Calendar.getInstance();
179
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
180
+        calendar.set(Calendar.MINUTE, 0);
181
+        calendar.set(Calendar.SECOND, 0);
182
+        calendar.set(Calendar.MILLISECOND, 0);
183
+
184
+        for (int i = 29; i >= 0; i--) {
185
+            Calendar cal = (Calendar) calendar.clone();
186
+            cal.add(Calendar.DAY_OF_MONTH, -i);
187
+            dates.add(cal.getTime());
188
+        }
189
+        return dates;
190
+    }
191
+
192
+    /**
193
+     * 格式化日期为字符串键值(yyyy-MM-dd)
194
+     */
195
+    public static String formatDateKey(Date date) {
196
+        if (Objects.isNull(date)) {
197
+            return "";
198
+        }
199
+        Calendar cal = Calendar.getInstance();
200
+        cal.setTime(date);
201
+        cal.set(Calendar.HOUR_OF_DAY, 0);
202
+        cal.set(Calendar.MINUTE, 0);
203
+        cal.set(Calendar.SECOND, 0);
204
+        cal.set(Calendar.MILLISECOND, 0);
205
+        return String.format("%04d-%02d-%02d",
206
+                cal.get(Calendar.YEAR),
207
+                cal.get(Calendar.MONTH) + 1,
208
+                cal.get(Calendar.DAY_OF_MONTH));
209
+    }
191
 }
210
 }

+ 2 - 2
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/OperationStationHourlyThroughput.java

@@ -53,12 +53,12 @@ public class OperationStationHourlyThroughput extends BaseEntity {
53
     @Excel(name = "通道号")
53
     @Excel(name = "通道号")
54
     private String laneId;
54
     private String laneId;
55
 
55
 
56
-    /** 记录日期(YYYYMMDD) */
56
+    /** 记录日期(yyyy-MM-dd) */
57
     @JsonFormat(pattern = "yyyy-MM-dd")
57
     @JsonFormat(pattern = "yyyy-MM-dd")
58
     @Excel(name = "记录日期", width = 20, dateFormat = "yyyy-MM-dd")
58
     @Excel(name = "记录日期", width = 20, dateFormat = "yyyy-MM-dd")
59
     private Date recordDate;
59
     private Date recordDate;
60
 
60
 
61
-    /** 小时(0:00~1:00、1:00~2:00、23:00~24:00等) */
61
+    /** 小时(0:00、1:00、2:00等) */
62
     @Excel(name = "小时")
62
     @Excel(name = "小时")
63
     private String hourOfDay;
63
     private String hourOfDay;
64
 
64
 

+ 4 - 0
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/AreaFlowVO.java

@@ -1,6 +1,8 @@
1
 package com.sundot.airport.ledger.domain.vo;
1
 package com.sundot.airport.ledger.domain.vo;
2
 
2
 
3
+import lombok.AllArgsConstructor;
3
 import lombok.Data;
4
 import lombok.Data;
5
+import lombok.NoArgsConstructor;
4
 
6
 
5
 import java.io.Serializable;
7
 import java.io.Serializable;
6
 
8
 
@@ -11,6 +13,8 @@ import java.io.Serializable;
11
  * @date 2026/5/19 16:55
13
  * @date 2026/5/19 16:55
12
  */
14
  */
13
 @Data
15
 @Data
16
+@NoArgsConstructor
17
+@AllArgsConstructor
14
 public class AreaFlowVO implements Serializable {
18
 public class AreaFlowVO implements Serializable {
15
     /**
19
     /**
16
      * 区域ID
20
      * 区域ID

+ 16 - 2
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/LaneThroughputResVO.java

@@ -1,8 +1,11 @@
1
 package com.sundot.airport.ledger.domain.vo;
1
 package com.sundot.airport.ledger.domain.vo;
2
 
2
 
3
-import lombok.Data;
3
+    import com.fasterxml.jackson.annotation.JsonFormat;
4
+    import lombok.AllArgsConstructor;
5
+    import lombok.Data;
6
+    import lombok.NoArgsConstructor;
4
 
7
 
5
-import java.io.Serializable;
8
+    import java.io.Serializable;
6
 import java.math.BigDecimal;
9
 import java.math.BigDecimal;
7
 import java.util.Date;
10
 import java.util.Date;
8
 
11
 
@@ -13,10 +16,13 @@ import java.util.Date;
13
  * @date 2026/5/19 15:27
16
  * @date 2026/5/19 15:27
14
  */
17
  */
15
 @Data
18
 @Data
19
+@NoArgsConstructor
20
+@AllArgsConstructor
16
 public class LaneThroughputResVO implements Serializable {
21
 public class LaneThroughputResVO implements Serializable {
17
     /**
22
     /**
18
      * 日期
23
      * 日期
19
      */
24
      */
25
+    @JsonFormat(pattern = "MM-dd")
20
     private Date recordDate;
26
     private Date recordDate;
21
 
27
 
22
     /**
28
     /**
@@ -38,4 +44,12 @@ public class LaneThroughputResVO implements Serializable {
38
      * 过检率(保留1位小数)
44
      * 过检率(保留1位小数)
39
      */
45
      */
40
     private BigDecimal throughputRate;
46
     private BigDecimal throughputRate;
47
+
48
+    public LaneThroughputResVO(Date date, String groupName) {
49
+        this.recordDate = date;
50
+        this.totalThroughput = 0;
51
+        this.totalRecord = 0;
52
+        this.throughputRate = java.math.BigDecimal.ZERO;
53
+        this.groupName = groupName;
54
+    }
41
 }
55
 }

+ 2 - 2
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/SeizeCategoryQuantityVO.java

@@ -15,9 +15,9 @@ public class SeizeCategoryQuantityVO implements Serializable {
15
     /**
15
     /**
16
      * 违规品类别名称(饼图名称)
16
      * 违规品类别名称(饼图名称)
17
      */
17
      */
18
-    private String categoryName;
18
+    private String itemName;
19
     /**
19
     /**
20
      * 该类别总查获数量(饼图数值)
20
      * 该类别总查获数量(饼图数值)
21
      */
21
      */
22
-    private Integer categoryNum;
22
+    private Integer itemNum;
23
 }
23
 }

+ 6 - 1
airport-ledger/src/main/java/com/sundot/airport/ledger/domain/vo/StationHourlyThroughputGroupResVO.java

@@ -14,11 +14,16 @@ import java.util.List;
14
 @Data
14
 @Data
15
 public class StationHourlyThroughputGroupResVO implements Serializable {
15
 public class StationHourlyThroughputGroupResVO implements Serializable {
16
     /**
16
     /**
17
-     * 小时(0,1,2...23
17
+     * 小时(2026-05-20 16:00
18
      */
18
      */
19
     private String hourOfDay;
19
     private String hourOfDay;
20
 
20
 
21
     /**
21
     /**
22
+     * 小时(16:00)
23
+     */
24
+    private String hour;
25
+
26
+    /**
22
      * 当前小时 所有区域总人流量
27
      * 当前小时 所有区域总人流量
23
      */
28
      */
24
     private Integer totalHourFlow;
29
     private Integer totalHourFlow;

+ 2 - 2
airport-ledger/src/main/java/com/sundot/airport/ledger/mapper/LedgerSeizureStatsMapper.java

@@ -71,11 +71,11 @@ public interface LedgerSeizureStatsMapper extends BaseMapper<LedgerSeizureStats>
71
      *
71
      *
72
      * @param query 查询参数
72
      * @param query 查询参数
73
      * @return List<SeizeCategoryQuantityVO>
73
      * @return List<SeizeCategoryQuantityVO>
74
-     * @method countSeizeSubjectCategoryQuantity
74
+     * @method countSeizeSubjectItemQuantity
75
      * @author PanHu Sun
75
      * @author PanHu Sun
76
      * @date 2026/5/20 14:40
76
      * @date 2026/5/20 14:40
77
      */
77
      */
78
-    List<SeizeCategoryQuantityVO> countSeizeSubjectCategoryQuantity(CountQueryReqVO query);
78
+    List<SeizeCategoryQuantityVO> countSeizeSubjectItemQuantity(CountQueryReqVO query);
79
 
79
 
80
     /**
80
     /**
81
      * 功能描述:查获工作区域分布
81
      * 功能描述:查获工作区域分布

+ 2 - 2
airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerSeizureStatsService.java

@@ -52,11 +52,11 @@ public interface ILedgerSeizureStatsService extends IService<LedgerSeizureStats>
52
      *
52
      *
53
      * @param countQueryReq 查询参数
53
      * @param countQueryReq 查询参数
54
      * @return List<SeizeCategoryQuantityVO>
54
      * @return List<SeizeCategoryQuantityVO>
55
-     * @method countSeizeSubjectCategoryQuantity
55
+     * @method countSeizeSubjectItemQuantity
56
      * @author PanHu Sun
56
      * @author PanHu Sun
57
      * @date 2026/5/20 14:46
57
      * @date 2026/5/20 14:46
58
      */
58
      */
59
-    List<SeizeCategoryQuantityVO> countSeizeSubjectCategoryQuantity(CountQueryReqVO countQueryReq);
59
+    List<SeizeCategoryQuantityVO> countSeizeSubjectItemQuantity(CountQueryReqVO countQueryReq);
60
 
60
 
61
     /**
61
     /**
62
      * 功能描述:查获工作区域分布
62
      * 功能描述:查获工作区域分布

+ 3 - 3
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerSeizureStatsServiceImpl.java

@@ -98,14 +98,14 @@ public class LedgerSeizureStatsServiceImpl extends ServiceImpl<LedgerSeizureStat
98
      *
98
      *
99
      * @param countQueryReq 查询参数
99
      * @param countQueryReq 查询参数
100
      * @return List<SeizeCategoryQuantityVO>
100
      * @return List<SeizeCategoryQuantityVO>
101
-     * @method countSeizeSubjectCategoryQuantity
101
+     * @method countSeizeSubjectItemQuantity
102
      * @author PanHu Sun
102
      * @author PanHu Sun
103
      * @date 2026/5/20 14:46
103
      * @date 2026/5/20 14:46
104
      */
104
      */
105
     @Override
105
     @Override
106
-    public List<SeizeCategoryQuantityVO> countSeizeSubjectCategoryQuantity(CountQueryReqVO countQueryReq) {
106
+    public List<SeizeCategoryQuantityVO> countSeizeSubjectItemQuantity(CountQueryReqVO countQueryReq) {
107
         // 无数据自动返回空数组,符合需求
107
         // 无数据自动返回空数组,符合需求
108
-        List<SeizeCategoryQuantityVO> seizeCategoryQuantityList = this.baseMapper.countSeizeSubjectCategoryQuantity(countQueryReq);
108
+        List<SeizeCategoryQuantityVO> seizeCategoryQuantityList = this.baseMapper.countSeizeSubjectItemQuantity(countQueryReq);
109
         return CollUtil.emptyIfNull(seizeCategoryQuantityList);
109
         return CollUtil.emptyIfNull(seizeCategoryQuantityList);
110
     }
110
     }
111
 
111
 

+ 56 - 5
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/OperationLanePeakThroughputServiceImpl.java

@@ -1,24 +1,31 @@
1
 package com.sundot.airport.ledger.service.impl;
1
 package com.sundot.airport.ledger.service.impl;
2
 
2
 
3
-import java.util.Collections;
4
-import java.util.List;
5
-import java.util.Objects;
6
-
7
 import cn.hutool.core.collection.CollUtil;
3
 import cn.hutool.core.collection.CollUtil;
8
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
4
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
5
+import com.google.common.collect.Lists;
9
 import com.sundot.airport.common.utils.DateUtils;
6
 import com.sundot.airport.common.utils.DateUtils;
10
 import com.sundot.airport.ledger.domain.OperationLanePeakThroughput;
7
 import com.sundot.airport.ledger.domain.OperationLanePeakThroughput;
11
 import com.sundot.airport.ledger.domain.vo.CountQueryReqVO;
8
 import com.sundot.airport.ledger.domain.vo.CountQueryReqVO;
12
 import com.sundot.airport.ledger.domain.vo.LaneThroughputResVO;
9
 import com.sundot.airport.ledger.domain.vo.LaneThroughputResVO;
13
 import com.sundot.airport.ledger.mapper.OperationLanePeakThroughputMapper;
10
 import com.sundot.airport.ledger.mapper.OperationLanePeakThroughputMapper;
14
 import com.sundot.airport.ledger.service.IOperationLanePeakThroughputService;
11
 import com.sundot.airport.ledger.service.IOperationLanePeakThroughputService;
12
+import lombok.extern.slf4j.Slf4j;
15
 import org.springframework.beans.factory.annotation.Autowired;
13
 import org.springframework.beans.factory.annotation.Autowired;
16
 import org.springframework.stereotype.Service;
14
 import org.springframework.stereotype.Service;
17
 import org.springframework.transaction.annotation.Transactional;
15
 import org.springframework.transaction.annotation.Transactional;
18
 
16
 
17
+import java.util.Collections;
18
+import java.util.Comparator;
19
+import java.util.Date;
20
+import java.util.List;
21
+import java.util.Map;
22
+import java.util.Objects;
23
+import java.util.stream.Collectors;
24
+
19
 /**
25
 /**
20
  * 通道日别高峰时段过检Service业务层处理
26
  * 通道日别高峰时段过检Service业务层处理
21
  */
27
  */
28
+@Slf4j
22
 @Service
29
 @Service
23
 public class OperationLanePeakThroughputServiceImpl extends ServiceImpl<OperationLanePeakThroughputMapper, OperationLanePeakThroughput>
30
 public class OperationLanePeakThroughputServiceImpl extends ServiceImpl<OperationLanePeakThroughputMapper, OperationLanePeakThroughput>
24
         implements IOperationLanePeakThroughputService {
31
         implements IOperationLanePeakThroughputService {
@@ -102,7 +109,51 @@ public class OperationLanePeakThroughputServiceImpl extends ServiceImpl<Operatio
102
         if (Objects.isNull(laneThroughputQuery.getDeptId()) && Objects.isNull(laneThroughputQuery.getTeamId()) && Objects.isNull(laneThroughputQuery.getGroupId())) {
109
         if (Objects.isNull(laneThroughputQuery.getDeptId()) && Objects.isNull(laneThroughputQuery.getTeamId()) && Objects.isNull(laneThroughputQuery.getGroupId())) {
103
             return Collections.emptyList();
110
             return Collections.emptyList();
104
         }
111
         }
112
+        
113
+        // 查询数据库中存在的日期数据
105
         List<LaneThroughputResVO> laneThroughputResList = this.baseMapper.countLanePeakThroughput(laneThroughputQuery);
114
         List<LaneThroughputResVO> laneThroughputResList = this.baseMapper.countLanePeakThroughput(laneThroughputQuery);
106
-        return CollUtil.emptyIfNull(laneThroughputResList);
115
+        laneThroughputResList = CollUtil.emptyIfNull(laneThroughputResList);
116
+        
117
+        log.info("SQL查询返回数据条数: {}", laneThroughputResList.size());
118
+        
119
+        // 生成近30天的日期列表
120
+        List<Date> last30Days = DateUtils.generateLast30Days();
121
+        
122
+        // 将查询结果按日期建立映射(只比较日期部分,忽略时间)
123
+        Map<String, LaneThroughputResVO> dataMap = laneThroughputResList.stream()
124
+                .collect(Collectors.toMap(
125
+                        vo -> DateUtils.formatDateKey(vo.getRecordDate()),
126
+                        vo -> vo,
127
+                        (existing, replacement) -> existing
128
+                ));
129
+        
130
+        log.info("数据Map中的日期键: {}", dataMap.keySet());
131
+
132
+        // 获取小组名称
133
+        String groupName = "";
134
+        if (CollUtil.isNotEmpty(laneThroughputResList)) {
135
+            groupName = laneThroughputResList.get(0).getGroupName();
136
+        }
137
+
138
+        // 补齐缺失的日期数据
139
+        List<LaneThroughputResVO> resultList = Lists.newArrayList();
140
+        for (Date date : last30Days) {
141
+            String dateKey = DateUtils.formatDateKey(date);
142
+            if (dataMap.containsKey(dateKey)) {
143
+                // 存在的日期,使用查询结果
144
+                resultList.add(dataMap.get(dateKey));
145
+            } else {
146
+                // 缺失的日期,补充0数据
147
+                LaneThroughputResVO emptyLaneThroughput = new LaneThroughputResVO(date, groupName);
148
+                resultList.add(emptyLaneThroughput);
149
+            }
150
+        }
151
+        
152
+        log.info("补齐后返回的总数据条数: {}", resultList.size());
153
+        
154
+        // 按日期升序排序
155
+        resultList.sort(Comparator.comparing(LaneThroughputResVO::getRecordDate));
156
+        
157
+        return resultList;
107
     }
158
     }
108
 }
159
 }

+ 153 - 34
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/OperationStationHourlyThroughputServiceImpl.java

@@ -1,25 +1,23 @@
1
 package com.sundot.airport.ledger.service.impl;
1
 package com.sundot.airport.ledger.service.impl;
2
 
2
 
3
-import java.util.Collections;
4
-import java.util.HashMap;
5
-import java.util.List;
6
-import java.util.Map;
7
-import java.util.Objects;
8
-import java.util.Set;
3
+import java.util.*;
9
 import java.util.stream.Collectors;
4
 import java.util.stream.Collectors;
10
 
5
 
11
 import cn.hutool.core.collection.CollUtil;
6
 import cn.hutool.core.collection.CollUtil;
12
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
8
+import com.google.common.collect.Lists;
13
 import com.google.common.collect.Maps;
9
 import com.google.common.collect.Maps;
14
 import com.sundot.airport.common.utils.DateUtils;
10
 import com.sundot.airport.common.utils.DateUtils;
15
 import com.sundot.airport.ledger.domain.OperationStationHourlyThroughput;
11
 import com.sundot.airport.ledger.domain.OperationStationHourlyThroughput;
16
 import com.sundot.airport.ledger.domain.vo.AreaFlowVO;
12
 import com.sundot.airport.ledger.domain.vo.AreaFlowVO;
13
+import com.sundot.airport.ledger.domain.vo.LaneThroughputResVO;
17
 import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputGroupResVO;
14
 import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputGroupResVO;
18
 import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputVO;
15
 import com.sundot.airport.ledger.domain.vo.StationHourlyThroughputVO;
19
 import com.sundot.airport.ledger.mapper.OperationStationHourlyThroughputMapper;
16
 import com.sundot.airport.ledger.mapper.OperationStationHourlyThroughputMapper;
20
 import com.sundot.airport.ledger.service.IOperationStationHourlyThroughputService;
17
 import com.sundot.airport.ledger.service.IOperationStationHourlyThroughputService;
21
 import com.sundot.airport.system.domain.BasePosition;
18
 import com.sundot.airport.system.domain.BasePosition;
22
 import com.sundot.airport.system.mapper.BasePositionMapper;
19
 import com.sundot.airport.system.mapper.BasePositionMapper;
20
+import lombok.extern.slf4j.Slf4j;
23
 import org.springframework.beans.factory.annotation.Autowired;
21
 import org.springframework.beans.factory.annotation.Autowired;
24
 import org.springframework.stereotype.Service;
22
 import org.springframework.stereotype.Service;
25
 import org.springframework.transaction.annotation.Transactional;
23
 import org.springframework.transaction.annotation.Transactional;
@@ -27,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
27
 /**
25
 /**
28
  * 站级时间段别总过检Service业务层处理
26
  * 站级时间段别总过检Service业务层处理
29
  */
27
  */
28
+@Slf4j
30
 @Service
29
 @Service
31
 public class OperationStationHourlyThroughputServiceImpl extends ServiceImpl<OperationStationHourlyThroughputMapper, OperationStationHourlyThroughput> implements IOperationStationHourlyThroughputService {
30
 public class OperationStationHourlyThroughputServiceImpl extends ServiceImpl<OperationStationHourlyThroughputMapper, OperationStationHourlyThroughput> implements IOperationStationHourlyThroughputService {
32
 
31
 
@@ -107,8 +106,15 @@ public class OperationStationHourlyThroughputServiceImpl extends ServiceImpl<Ope
107
     @Override
106
     @Override
108
     public List<StationHourlyThroughputGroupResVO> countStationHourlyThroughput() {
107
     public List<StationHourlyThroughputGroupResVO> countStationHourlyThroughput() {
109
         List<StationHourlyThroughputVO> stationHourlyThroughputList = this.baseMapper.countStationHourlyThroughput();
108
         List<StationHourlyThroughputVO> stationHourlyThroughputList = this.baseMapper.countStationHourlyThroughput();
110
-        if (CollUtil.isEmpty(stationHourlyThroughputList)) {
111
-            return Collections.emptyList();
109
+        stationHourlyThroughputList = CollUtil.emptyIfNull(stationHourlyThroughputList);
110
+
111
+        log.info("SQL查询返回数据条数: {}", stationHourlyThroughputList.size());
112
+        if (!stationHourlyThroughputList.isEmpty()) {
113
+            log.info("SQL查询返回的时间点列表: {}", 
114
+                    stationHourlyThroughputList.stream()
115
+                            .map(StationHourlyThroughputVO::getHourOfDay)
116
+                            .distinct()
117
+                            .collect(Collectors.toList()));
112
         }
118
         }
113
 
119
 
114
         Map<Long, BasePosition> areaInfoMap = Maps.newHashMap();
120
         Map<Long, BasePosition> areaInfoMap = Maps.newHashMap();
@@ -124,33 +130,146 @@ public class OperationStationHourlyThroughputServiceImpl extends ServiceImpl<Ope
124
             areaInfoMap = CollUtil.emptyIfNull(basePositions).stream().collect(Collectors.toMap(BasePosition::getId, v -> v));
130
             areaInfoMap = CollUtil.emptyIfNull(basePositions).stream().collect(Collectors.toMap(BasePosition::getId, v -> v));
125
         }
131
         }
126
 
132
 
127
-        // 2. 核心:按小时分组 → 组装成前端需要的层级结构
128
-        Map<String, List<StationHourlyThroughputVO>> hourGroupMap = stationHourlyThroughputList.stream().collect(Collectors.groupingBy(StationHourlyThroughputVO::getHourOfDay));
133
+        // 2. 按时间点分组
134
+        Map<String, List<StationHourlyThroughputVO>> hourGroupMap = stationHourlyThroughputList.stream()
135
+                .collect(Collectors.groupingBy(StationHourlyThroughputVO::getHourOfDay));
136
+
137
+        // 3. 生成近24个具体时间点(从当前时间向前推24小时)
138
+        List<String> last24Hours = this.generateLast24Hours();
139
+        
140
+        log.info("需要补齐的24个时间点: {}", last24Hours);
129
 
141
 
130
         Map<Long, BasePosition> finalAreaInfoMap = areaInfoMap;
142
         Map<Long, BasePosition> finalAreaInfoMap = areaInfoMap;
131
-        return hourGroupMap.entrySet().stream().map(entry -> {
132
-            String hour = entry.getKey();
133
-            List<StationHourlyThroughputVO> hourDataList = entry.getValue();
134
-
135
-            // 构建区域列表
136
-            List<AreaFlowVO> areaList = hourDataList.stream().map(stats -> {
137
-                BasePosition basePosition = finalAreaInfoMap.get(stats.getAreaId());
138
-
139
-                AreaFlowVO areaFlowVO = new AreaFlowVO();
140
-                areaFlowVO.setAreaId(stats.getAreaId());
141
-                areaFlowVO.setAreaName(Objects.nonNull(basePosition) ? basePosition.getName() : "");
142
-                areaFlowVO.setAreaFlow(stats.getAreaFlow());
143
-                return areaFlowVO;
144
-            }).collect(Collectors.toList());
145
-
146
-            // 构建小时分组对象
147
-            StationHourlyThroughputGroupResVO groupVO = new StationHourlyThroughputGroupResVO();
148
-            groupVO.setHourOfDay(hour);
149
-            // 总人流量(取第一条即可,同小时数据总流量一致)
150
-            groupVO.setTotalHourFlow(hourDataList.get(0).getTotalHourFlow());
151
-            // 区域信息
152
-            groupVO.setAreaList(areaList);
153
-            return groupVO;
154
-        }).collect(Collectors.toList());
143
+        
144
+        // 4. 补齐24个时间点数据
145
+        List<StationHourlyThroughputGroupResVO> resultList = Lists.newArrayList();
146
+        for (String hourTime : last24Hours) {
147
+            // 处理日期 转换hourTime格式的日期,例如:2026-05-21 00:00转成0:00,2026-05-21 01:00转成01:00,2026-05-21 11:00转成11:00
148
+            // 提取小时和分钟部分(去掉日期)
149
+            String hourOnly = this.extractHourAndMinute(hourTime);
150
+
151
+            if (hourGroupMap.containsKey(hourTime)) {
152
+                // 存在数据的时间点,正常组装
153
+                List<StationHourlyThroughputVO> hourDataList = hourGroupMap.get(hourTime);
154
+                
155
+                List<AreaFlowVO> areaList = hourDataList.stream().map(stats -> {
156
+                    BasePosition basePosition = finalAreaInfoMap.get(stats.getAreaId());
157
+                    AreaFlowVO areaFlowVO = new AreaFlowVO();
158
+                    areaFlowVO.setAreaId(stats.getAreaId());
159
+                    areaFlowVO.setAreaName(Objects.nonNull(basePosition) ? basePosition.getName() : "");
160
+                    areaFlowVO.setAreaFlow(stats.getAreaFlow());
161
+                    return areaFlowVO;
162
+                }).collect(Collectors.toList());
163
+
164
+                // 补充缺失的区域信息
165
+                if (CollUtil.isEmpty(areaList)){
166
+                    areaInfoMap.forEach((id, basePosition) -> {
167
+                        areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
168
+                    });
169
+                } else {
170
+                    if (areaList.size() != areaInfoMap.size()) {
171
+                        areaInfoMap.forEach((id, basePosition) -> {
172
+                            AreaFlowVO newAreaFlow = areaList.stream().filter(areaFlowVO -> areaFlowVO.getAreaId().equals(id)).findFirst().orElse(null);
173
+                            if (Objects.isNull(newAreaFlow)) {
174
+                                areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
175
+                            }
176
+                        });
177
+                    }
178
+                }
179
+
180
+                // 按区域id升序排序
181
+                if (CollUtil.isNotEmpty(areaList)){
182
+                    areaList.sort(Comparator.comparing(AreaFlowVO::getAreaId));
183
+                }
184
+
185
+                StationHourlyThroughputGroupResVO groupVO = new StationHourlyThroughputGroupResVO();
186
+                groupVO.setHourOfDay(hourTime);
187
+                groupVO.setHour(hourOnly);
188
+                groupVO.setTotalHourFlow(hourDataList.get(0).getTotalHourFlow());
189
+                groupVO.setAreaList(areaList);
190
+                resultList.add(groupVO);
191
+            } else {
192
+                List<AreaFlowVO> areaList = Lists.newArrayList();
193
+                areaInfoMap.forEach((id, basePosition) -> {
194
+                    areaList.add(new AreaFlowVO(id, basePosition.getName(), 0));
195
+                });
196
+
197
+                // 按区域id升序排序
198
+                if (CollUtil.isNotEmpty(areaList)){
199
+                    areaList.sort(Comparator.comparing(AreaFlowVO::getAreaId));
200
+                }
201
+
202
+                // 缺失的时间点,补充空数据
203
+                StationHourlyThroughputGroupResVO emptyVO = new StationHourlyThroughputGroupResVO();
204
+                emptyVO.setHourOfDay(hourTime);
205
+                emptyVO.setHour(hourOnly);
206
+                emptyVO.setTotalHourFlow(0);
207
+                emptyVO.setAreaList(areaList);
208
+                resultList.add(emptyVO);
209
+            }
210
+        }
211
+        
212
+        log.info("补齐后返回的总时间点数: {}", resultList.size());
213
+        return resultList;
214
+    }
215
+    
216
+    /**
217
+     * 生成近24个具体时间点(从当前时间向前推24小时)
218
+     * 格式:yyyy-MM-dd HH:00
219
+     */
220
+    private List<String> generateLast24Hours() {
221
+        List<String> hours = new ArrayList<>();
222
+        Calendar calendar = Calendar.getInstance();
223
+        calendar.set(Calendar.MINUTE, 0);
224
+        calendar.set(Calendar.SECOND, 0);
225
+        calendar.set(Calendar.MILLISECOND, 0);
226
+        
227
+        // 从当前小时向前推23小时,共24个时间点
228
+        for (int i = 23; i >= 0; i--) {
229
+            Calendar cal = (Calendar) calendar.clone();
230
+            cal.add(Calendar.HOUR_OF_DAY, -i);
231
+            
232
+            String hourTime = String.format("%04d-%02d-%02d %02d:00",
233
+                    cal.get(Calendar.YEAR),
234
+                    cal.get(Calendar.MONTH) + 1,
235
+                    cal.get(Calendar.DAY_OF_MONTH),
236
+                    cal.get(Calendar.HOUR_OF_DAY));
237
+            hours.add(hourTime);
238
+        }
239
+        
240
+        return hours;
241
+    }
242
+    
243
+    /**
244
+     * 从完整日期时间中提取小时和分钟部分
245
+     * 例如:2026-05-21 00:00 → 0:00
246
+     *      2026-05-21 01:00 → 01:00
247
+     *      2026-05-21 11:00 → 11:00
248
+     * 
249
+     * @param hourTime 完整日期时间字符串(格式:yyyy-MM-dd HH:00)
250
+     * @return 小时和分钟字符串(格式:H:00 或 HH:00)
251
+     */
252
+    private String extractHourAndMinute(String hourTime) {
253
+        if (hourTime == null || hourTime.trim().isEmpty()) {
254
+            return "";
255
+        }
256
+        
257
+        // 按空格分割,取时间部分
258
+        String[] parts = hourTime.split(" ");
259
+        if (parts.length < 2) {
260
+            return hourTime;
261
+        }
262
+        
263
+        String timePart = parts[1]; // 获取 "00:00" 部分
264
+        
265
+        // 去掉小时的前导0(如果有的话)
266
+        String[] timeComponents = timePart.split(":");
267
+        if (timeComponents.length >= 2) {
268
+            int hour = Integer.parseInt(timeComponents[0]);
269
+            String minute = timeComponents[1];
270
+            return hour + ":" + minute;
271
+        }
272
+        
273
+        return timePart;
155
     }
274
     }
156
 }
275
 }

+ 13 - 11
airport-ledger/src/main/resources/mapper/ledger/LedgerSeizureStatsMapper.xml

@@ -152,10 +152,10 @@
152
         </where>
152
         </where>
153
         GROUP BY
153
         GROUP BY
154
             <choose>
154
             <choose>
155
-                <when test="groupId != null">inspector_id</when>
156
-                <when test="teamId != null">group_id</when>
157
-                <when test="deptId != null">team_id</when>
158
-                <otherwise>dept_id</otherwise>
155
+                <when test="groupId != null">inspector_id, inspector_name</when>
156
+                <when test="teamId != null">group_id, group_name</when>
157
+                <when test="deptId != null">team_id, team_name</when>
158
+                <otherwise>dept_id, dept_name</otherwise>
159
             </choose>
159
             </choose>
160
         ORDER BY seizeNum DESC
160
         ORDER BY seizeNum DESC
161
     </select>
161
     </select>
@@ -169,17 +169,17 @@
169
         </where>
169
         </where>
170
     </select>
170
     </select>
171
 
171
 
172
-    <select id="countSeizeSubjectCategoryQuantity" parameterType="com.sundot.airport.ledger.domain.vo.CountQueryReqVO" resultType="com.sundot.airport.ledger.domain.vo.SeizeCategoryQuantityVO">
173
-        SELECT item_category AS categoryName, IFNULL(SUM(item_quantity), 0) AS categoryNum
172
+    <select id="countSeizeSubjectItemQuantity" parameterType="com.sundot.airport.ledger.domain.vo.CountQueryReqVO" resultType="com.sundot.airport.ledger.domain.vo.SeizeCategoryQuantityVO">
173
+        SELECT item_name AS itemName, IFNULL(SUM(item_quantity), 0) AS itemNum
174
         FROM ledger_seizure_stats
174
         FROM ledger_seizure_stats
175
         <where>
175
         <where>
176
             <include refid="FILTER_FIXED_CRITERIA_SQL"/>
176
             <include refid="FILTER_FIXED_CRITERIA_SQL"/>
177
             <!-- 过滤空类别,避免脏数据 -->
177
             <!-- 过滤空类别,避免脏数据 -->
178
-            AND item_category IS NOT NULL
179
-            AND item_category != ''
178
+            AND item_name IS NOT NULL
179
+            AND item_name != ''
180
         </where>
180
         </where>
181
-        GROUP BY item_category
182
-        ORDER BY categoryNum DESC
181
+        GROUP BY item_name
182
+        ORDER BY itemNum DESC
183
     </select>
183
     </select>
184
 
184
 
185
     <select id="countSeizeAreaQuantity" parameterType="com.sundot.airport.ledger.domain.vo.CountQueryReqVO" resultType="com.sundot.airport.ledger.domain.vo.SeizureAreaVO">
185
     <select id="countSeizeAreaQuantity" parameterType="com.sundot.airport.ledger.domain.vo.CountQueryReqVO" resultType="com.sundot.airport.ledger.domain.vo.SeizureAreaVO">
@@ -196,7 +196,9 @@
196
 
196
 
197
     <sql id="FILTER_FIXED_CRITERIA_SQL">
197
     <sql id="FILTER_FIXED_CRITERIA_SQL">
198
         del_flag = '0'
198
         del_flag = '0'
199
-        AND record_date BETWEEN #{startDate} AND #{endDate}
199
+        <if test="startDate != null and endDate != null">
200
+            AND record_date BETWEEN #{startDate,jdbcType=DATE} AND #{endDate,jdbcType=DATE}
201
+        </if>
200
         <include refid="FILTER_CRITERIA_SQL"/>
202
         <include refid="FILTER_CRITERIA_SQL"/>
201
     </sql>
203
     </sql>
202
 
204
 

+ 3 - 1
airport-ledger/src/main/resources/mapper/ledger/LedgerUnsafeEventMapper.xml

@@ -94,7 +94,9 @@
94
     
94
     
95
     <sql id="FILTER_CRITERIA_SQL">
95
     <sql id="FILTER_CRITERIA_SQL">
96
         del_flag = '0'
96
         del_flag = '0'
97
-        AND record_date BETWEEN #{startDate} AND #{endDate}
97
+        <if test="startDate != null and endDate != null">
98
+            AND record_date BETWEEN #{startDate,jdbcType=DATE} AND #{endDate,jdbcType=DATE}
99
+        </if>
98
         <!-- 三级联动筛选 -->
100
         <!-- 三级联动筛选 -->
99
         <if test="deptId != null">AND dept_id = #{deptId}</if>
101
         <if test="deptId != null">AND dept_id = #{deptId}</if>
100
         <if test="teamId != null">AND team_id = #{teamId}</if>
102
         <if test="teamId != null">AND team_id = #{teamId}</if>

+ 9 - 27
airport-ledger/src/main/resources/mapper/ledger/OperationLanePeakThroughputMapper.xml

@@ -54,15 +54,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
54
             record_date AS recordDate,
54
             record_date AS recordDate,
55
             <!-- 动态分组名称:小组>班组>部门 -->
55
             <!-- 动态分组名称:小组>班组>部门 -->
56
             <choose>
56
             <choose>
57
-                <when test="groupId != null">
58
-                    group_name AS groupName
59
-                </when>
60
-                <when test="teamId != null">
61
-                    team_name AS groupName
62
-                </when>
63
-                <when test="deptId != null">
64
-                    dept_name AS groupName
65
-                </when>
57
+                <when test="groupId != null">group_name AS groupName</when>
58
+                <when test="teamId != null">team_name AS groupName</when>
59
+                <when test="deptId != null">dept_name AS groupName</when>
66
             </choose>,
60
             </choose>,
67
             SUM(throughput) AS totalThroughput,
61
             SUM(throughput) AS totalThroughput,
68
             COUNT(*) AS totalRecord,
62
             COUNT(*) AS totalRecord,
@@ -75,27 +69,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
75
             AND record_date >= DATE_SUB(CURDATE(), INTERVAL 29 DAY)
69
             AND record_date >= DATE_SUB(CURDATE(), INTERVAL 29 DAY)
76
             AND record_date &lt;= CURDATE()
70
             AND record_date &lt;= CURDATE()
77
             <!-- 三级联动动态筛选 -->
71
             <!-- 三级联动动态筛选 -->
78
-            <if test="deptId != null">
79
-                AND dept_id = #{deptId}
80
-            </if>
81
-            <if test="teamId != null">
82
-                AND team_id = #{teamId}
83
-            </if>
84
-            <if test="groupId != null">
85
-                AND group_id = #{groupId}
86
-            </if>
72
+            <if test="deptId != null">AND dept_id = #{deptId}</if>
73
+            <if test="teamId != null">AND team_id = #{teamId}</if>
74
+            <if test="groupId != null">AND group_id = #{groupId}</if>
87
             <!-- 动态分组:按选中层级+日期分组 -->
75
             <!-- 动态分组:按选中层级+日期分组 -->
88
         GROUP BY
76
         GROUP BY
89
             <choose>
77
             <choose>
90
-                <when test="groupId != null">
91
-                    group_id, record_date
92
-                </when>
93
-                <when test="teamId != null">
94
-                    team_id, record_date
95
-                </when>
96
-                <when test="deptId != null">
97
-                    dept_id, record_date
98
-                </when>
78
+                <when test="groupId != null">group_id, record_date, group_name</when>
79
+                <when test="teamId != null">team_id, record_date, team_name</when>
80
+                <when test="deptId != null">dept_id, record_date, dept_name</when>
99
             </choose>
81
             </choose>
100
         <!-- 按日期升序,大屏展示顺序 -->
82
         <!-- 按日期升序,大屏展示顺序 -->
101
         ORDER BY record_date ASC
83
         ORDER BY record_date ASC

+ 21 - 8
airport-ledger/src/main/resources/mapper/ledger/OperationStationHourlyThroughputMapper.xml

@@ -53,25 +53,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
53
 
53
 
54
     <select id="countStationHourlyThroughput" resultType="com.sundot.airport.ledger.domain.vo.StationHourlyThroughputVO">
54
     <select id="countStationHourlyThroughput" resultType="com.sundot.airport.ledger.domain.vo.StationHourlyThroughputVO">
55
         SELECT
55
         SELECT
56
-            t.hour_of_day AS hourOfDay,
56
+            DATE_FORMAT(STR_TO_DATE(CONCAT(t.record_date, ' ', t.hour_of_day), '%Y-%m-%d %H:%i'), '%Y-%m-%d %H:00') AS hourOfDay,
57
             t.area_id AS areaId,
57
             t.area_id AS areaId,
58
             IFNULL(SUM(t.throughput), 0) AS areaFlow,
58
             IFNULL(SUM(t.throughput), 0) AS areaFlow,
59
-            t.total_hour_flow AS totalHourFlow
59
+            IFNULL(total_flow.total_hour_flow, 0) AS totalHourFlow
60
         FROM (
60
         FROM (
61
             SELECT
61
             SELECT
62
+                record_date,
62
                 hour_of_day,
63
                 hour_of_day,
63
                 area_id,
64
                 area_id,
64
-                throughput,
65
-                SUM(throughput) OVER (PARTITION BY hour_of_day) AS total_hour_flow
65
+                throughput
66
             FROM operation_station_hourly_throughput
66
             FROM operation_station_hourly_throughput
67
             WHERE
67
             WHERE
68
                 del_flag = '0'
68
                 del_flag = '0'
69
                 AND hour_of_day IS NOT NULL
69
                 AND hour_of_day IS NOT NULL
70
                 AND hour_of_day != ''
70
                 AND hour_of_day != ''
71
-            -- 近24小时自动匹配
72
-            AND STR_TO_DATE(CONCAT(record_date, hour_of_day), '%Y%m%d%H') >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
71
+                -- 近24小时自动匹配
72
+                AND STR_TO_DATE(CONCAT(record_date, ' ', hour_of_day), '%Y-%m-%d %H:%i') >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
73
         ) t
73
         ) t
74
-        GROUP BY t.hour_of_day, t.area_id
75
-        ORDER BY t.hour_of_day ASC
74
+        LEFT JOIN (
75
+            SELECT
76
+                DATE_FORMAT(STR_TO_DATE(CONCAT(record_date, ' ', hour_of_day), '%Y-%m-%d %H:%i'), '%Y-%m-%d %H:00') AS hour_time,
77
+                SUM(throughput) AS total_hour_flow
78
+            FROM operation_station_hourly_throughput
79
+            WHERE
80
+                del_flag = '0'
81
+                AND hour_of_day IS NOT NULL
82
+                AND hour_of_day != ''
83
+                -- 近24小时自动匹配
84
+                AND STR_TO_DATE(CONCAT(record_date, ' ', hour_of_day), '%Y-%m-%d %H:%i') >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
85
+            GROUP BY hour_time
86
+        ) total_flow ON DATE_FORMAT(STR_TO_DATE(CONCAT(t.record_date, ' ', t.hour_of_day), '%Y-%m-%d %H:%i'), '%Y-%m-%d %H:00') = total_flow.hour_time
87
+        GROUP BY hourOfDay, t.area_id, total_flow.total_hour_flow
88
+        ORDER BY hourOfDay ASC
76
     </select>
89
     </select>
77
 </mapper>
90
 </mapper>

+ 1 - 1
airport-system/src/main/java/com/sundot/airport/system/mapper/BasePositionMapper.java

@@ -79,7 +79,7 @@ public interface BasePositionMapper {
79
      * @author PanHu Sun
79
      * @author PanHu Sun
80
      * @date 2026/5/20 9:36
80
      * @date 2026/5/20 9:36
81
      */
81
      */
82
-    List<BasePosition> selectPositionListByIds(Set<Long> ids);
82
+    List<BasePosition> selectPositionListByIds(@Param("ids") Set<Long> ids);
83
 
83
 
84
     /**
84
     /**
85
      * 修改子元素关系
85
      * 修改子元素关系

+ 2 - 2
sql/station_hourly_throughput.sql

@@ -11,8 +11,8 @@ CREATE TABLE `operation_station_hourly_throughput` (
11
   `group_id` bigint(20) DEFAULT NULL COMMENT '通道/小组ID',
11
   `group_id` bigint(20) DEFAULT NULL COMMENT '通道/小组ID',
12
   `group_name` varchar(100) DEFAULT NULL COMMENT '通道/小组',
12
   `group_name` varchar(100) DEFAULT NULL COMMENT '通道/小组',
13
   `lane_id` varchar(50) DEFAULT NULL COMMENT '通道号',
13
   `lane_id` varchar(50) DEFAULT NULL COMMENT '通道号',
14
-  `record_date` varchar(8) DEFAULT NULL COMMENT '记录日期(YYYYMMDD)',
15
-  `hour_of_day` varchar(20) DEFAULT NULL COMMENT '小时(0:00~1:00、1:00~2:00、23:00~24:00等)',
14
+  `record_date` varchar(8) DEFAULT NULL COMMENT '记录日期(yyyy-MM-ddYYYYMMDD)',
15
+  `hour_of_day` varchar(20) DEFAULT NULL COMMENT '小时(0:00、1:00、2:00等)',
16
   `throughput` int(11) DEFAULT NULL COMMENT '过检人数',
16
   `throughput` int(11) DEFAULT NULL COMMENT '过检人数',
17
   `throughput_rate` decimal(10,2) DEFAULT NULL COMMENT '过检率',
17
   `throughput_rate` decimal(10,2) DEFAULT NULL COMMENT '过检率',
18
   `remark` varchar(500) DEFAULT NULL COMMENT '备注',
18
   `remark` varchar(500) DEFAULT NULL COMMENT '备注',