Kaynağa Gözat

速率表大屏

chenshudong 3 gün önce
ebeveyn
işleme
205f50b569

+ 66 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/blocked/BlockedRateScreenController.java

@@ -0,0 +1,66 @@
1
+package com.sundot.airport.web.controller.blocked;
2
+
3
+import com.sundot.airport.blocked.dto.BlockedRateScreenBrigadeDto;
4
+import com.sundot.airport.blocked.dto.BlockedRateScreenT1Dto;
5
+import com.sundot.airport.blocked.dto.BlockedRateScreenT2Dto;
6
+import com.sundot.airport.blocked.service.IBlockedRateScreenService;
7
+import com.sundot.airport.common.core.controller.BaseController;
8
+import com.sundot.airport.common.core.domain.AjaxResult;
9
+import com.sundot.airport.common.core.domain.BlockedRateQueryParamDto;
10
+import org.springframework.beans.factory.annotation.Autowired;
11
+import org.springframework.web.bind.annotation.GetMapping;
12
+import org.springframework.web.bind.annotation.RequestMapping;
13
+import org.springframework.web.bind.annotation.RestController;
14
+
15
+import java.util.List;
16
+
17
+/**
18
+ * 速率大屏Controller
19
+ *
20
+ * @author ruoyi
21
+ * @date 2026-04-15
22
+ */
23
+@RestController
24
+@RequestMapping("/blocked/rate/screen")
25
+public class BlockedRateScreenController extends BaseController {
26
+
27
+    @Autowired
28
+    private IBlockedRateScreenService blockedRateScreenService;
29
+
30
+    /**
31
+     * T1速率统计数据
32
+     */
33
+    @GetMapping("/t1")
34
+    public AjaxResult t1(BlockedRateQueryParamDto dto) {
35
+        List<BlockedRateScreenT1Dto> result = blockedRateScreenService.t1(dto);
36
+        return success(result);
37
+    }
38
+
39
+    /**
40
+     * T2速率统计数据
41
+     */
42
+    @GetMapping("/t2")
43
+    public AjaxResult t2(BlockedRateQueryParamDto dto) {
44
+        List<BlockedRateScreenT2Dto> result = blockedRateScreenService.t2(dto);
45
+        return success(result);
46
+    }
47
+
48
+    /**
49
+     * 国内速率统计数据
50
+     */
51
+    @GetMapping("/domestic")
52
+    public AjaxResult domestic(BlockedRateQueryParamDto dto) {
53
+        List<BlockedRateScreenBrigadeDto> result = blockedRateScreenService.domestic(dto);
54
+        return success(result);
55
+    }
56
+
57
+    /**
58
+     * 国际速率统计数据
59
+     */
60
+    @GetMapping("/international")
61
+    public AjaxResult international(BlockedRateQueryParamDto dto) {
62
+        List<BlockedRateScreenBrigadeDto> result = blockedRateScreenService.international(dto);
63
+        return success(result);
64
+    }
65
+
66
+}

+ 41 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/dto/BlockedRateScreenBrigadeDto.java

@@ -0,0 +1,41 @@
1
+package com.sundot.airport.blocked.dto;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import lombok.Data;
5
+import org.springframework.format.annotation.DateTimeFormat;
6
+
7
+import java.math.BigDecimal;
8
+import java.util.Date;
9
+
10
+/**
11
+ * 速率-国内/国际统计数据
12
+ *
13
+ * @author ruoyi
14
+ * @date 2026-04-15
15
+ */
16
+@Data
17
+public class BlockedRateScreenBrigadeDto {
18
+
19
+    /**
20
+     * 日期(格式:yyyy-MM-dd)
21
+     */
22
+    @JsonFormat(pattern = "yyyy-MM-dd")
23
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
24
+    private Date statDate;
25
+
26
+    /**
27
+     * 当班大队ID
28
+     */
29
+    private Long dutyBrigadeId;
30
+
31
+    /**
32
+     * 当班大队名称
33
+     */
34
+    private String dutyBrigadeName;
35
+
36
+    /**
37
+     * 平均速率
38
+     */
39
+    private BigDecimal avgRatePeak;
40
+
41
+}

+ 36 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/dto/BlockedRateScreenT1Dto.java

@@ -0,0 +1,36 @@
1
+package com.sundot.airport.blocked.dto;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import lombok.Data;
5
+import org.springframework.format.annotation.DateTimeFormat;
6
+
7
+import java.math.BigDecimal;
8
+import java.util.Date;
9
+
10
+/**
11
+ * 速率-T1统计数据
12
+ *
13
+ * @author ruoyi
14
+ * @date 2026-04-15
15
+ */
16
+@Data
17
+public class BlockedRateScreenT1Dto {
18
+
19
+    /**
20
+     * 日期(格式:yyyy-MM-dd)
21
+     */
22
+    @JsonFormat(pattern = "yyyy-MM-dd")
23
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
24
+    private Date statDate;
25
+
26
+    /**
27
+     * T1-A区速率(高峰期时段)
28
+     */
29
+    private BigDecimal t1AAreaRatePeak;
30
+
31
+    /**
32
+     * T1-B区速率(高峰期时段)
33
+     */
34
+    private BigDecimal t1BAreaRatePeak;
35
+
36
+}

+ 36 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/dto/BlockedRateScreenT2Dto.java

@@ -0,0 +1,36 @@
1
+package com.sundot.airport.blocked.dto;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import lombok.Data;
5
+import org.springframework.format.annotation.DateTimeFormat;
6
+
7
+import java.math.BigDecimal;
8
+import java.util.Date;
9
+
10
+/**
11
+ * 速率-T2统计数据
12
+ *
13
+ * @author ruoyi
14
+ * @date 2026-04-15
15
+ */
16
+@Data
17
+public class BlockedRateScreenT2Dto {
18
+
19
+    /**
20
+     * 日期(格式:yyyy-MM-dd)
21
+     */
22
+    @JsonFormat(pattern = "yyyy-MM-dd")
23
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
24
+    private Date statDate;
25
+
26
+    /**
27
+     * T2-国内速率(高峰期时段)
28
+     */
29
+    private BigDecimal t2DomesticRatePeak;
30
+
31
+    /**
32
+     * T2-国际速率(高峰期时段)
33
+     */
34
+    private BigDecimal t2InternationalRatePeak;
35
+
36
+}

+ 11 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/mapper/BlockedRateScreenMapper.java

@@ -0,0 +1,11 @@
1
+package com.sundot.airport.blocked.mapper;
2
+
3
+/**
4
+ * 速率大屏Mapper接口
5
+ *
6
+ * @author ruoyi
7
+ * @date 2026-04-13
8
+ */
9
+public interface BlockedRateScreenMapper {
10
+
11
+}

+ 50 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/service/IBlockedRateScreenService.java

@@ -0,0 +1,50 @@
1
+package com.sundot.airport.blocked.service;
2
+
3
+import com.sundot.airport.blocked.dto.BlockedRateScreenBrigadeDto;
4
+import com.sundot.airport.blocked.dto.BlockedRateScreenT1Dto;
5
+import com.sundot.airport.blocked.dto.BlockedRateScreenT2Dto;
6
+import com.sundot.airport.common.core.domain.BlockedRateQueryParamDto;
7
+
8
+import java.util.List;
9
+
10
+/**
11
+ * 速率大屏Service接口
12
+ *
13
+ * @author ruoyi
14
+ * @date 2026-04-13
15
+ */
16
+public interface IBlockedRateScreenService {
17
+
18
+    /**
19
+     * T1速率统计数据
20
+     *
21
+     * @param dto 上行参数
22
+     * @return 结果
23
+     */
24
+    public List<BlockedRateScreenT1Dto> t1(BlockedRateQueryParamDto dto);
25
+
26
+    /**
27
+     * T2速率统计数据
28
+     *
29
+     * @param dto 上行参数
30
+     * @return 结果
31
+     */
32
+    public List<BlockedRateScreenT2Dto> t2(BlockedRateQueryParamDto dto);
33
+
34
+    /**
35
+     * 国内速率统计数据
36
+     *
37
+     * @param dto 上行参数
38
+     * @return 结果
39
+     */
40
+    public List<BlockedRateScreenBrigadeDto> domestic(BlockedRateQueryParamDto dto);
41
+
42
+    /**
43
+     * 国际速率统计数据
44
+     *
45
+     * @param dto 上行参数
46
+     * @return 结果
47
+     */
48
+    public List<BlockedRateScreenBrigadeDto> international(BlockedRateQueryParamDto dto);
49
+
50
+}

+ 249 - 0
airport-blocked/src/main/java/com/sundot/airport/blocked/service/impl/BlockedRateScreenServiceImpl.java

@@ -0,0 +1,249 @@
1
+package com.sundot.airport.blocked.service.impl;
2
+
3
+import com.sundot.airport.blocked.domain.BlockedRate;
4
+import com.sundot.airport.blocked.dto.BlockedRateScreenBrigadeDto;
5
+import com.sundot.airport.blocked.dto.BlockedRateScreenT1Dto;
6
+import com.sundot.airport.blocked.dto.BlockedRateScreenT2Dto;
7
+import com.sundot.airport.blocked.mapper.BlockedRateMapper;
8
+import com.sundot.airport.blocked.mapper.BlockedRateScreenMapper;
9
+import com.sundot.airport.blocked.service.IBlockedRateScreenService;
10
+import com.sundot.airport.common.core.domain.BlockedRateQueryParamDto;
11
+import com.sundot.airport.common.core.domain.entity.SysDept;
12
+import com.sundot.airport.common.utils.BlockedDateUtils;
13
+import com.sundot.airport.system.service.ISysDeptService;
14
+import org.springframework.beans.factory.annotation.Autowired;
15
+import org.springframework.stereotype.Service;
16
+
17
+import java.math.BigDecimal;
18
+import java.math.RoundingMode;
19
+import java.util.ArrayList;
20
+import java.util.Arrays;
21
+import java.util.Collections;
22
+import java.util.Date;
23
+import java.util.List;
24
+import java.util.Map;
25
+import java.util.stream.Collectors;
26
+
27
+/**
28
+ * 速率大屏Service业务层处理
29
+ *
30
+ * @author ruoyi
31
+ * @date 2026-04-13
32
+ */
33
+@Service
34
+public class BlockedRateScreenServiceImpl implements IBlockedRateScreenService {
35
+
36
+    // 默认的精度
37
+    private static final int SCALE = 2;
38
+    // 默认的舍入模式
39
+    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP;
40
+    // 目标大队名称列表
41
+    private static final List<String> BRIGADE_NAMES = Arrays.asList("安检一大队", "安检二大队", "安检三大队");
42
+
43
+    @Autowired
44
+    private BlockedRateScreenMapper blockedRateScreenMapper;
45
+    @Autowired
46
+    private BlockedRateMapper blockedRateMapper;
47
+    @Autowired
48
+    private ISysDeptService sysDeptService;
49
+
50
+    /**
51
+     * T1速率统计数据
52
+     *
53
+     * @param dto 上行参数
54
+     * @return 结果
55
+     */
56
+    @Override
57
+    public List<BlockedRateScreenT1Dto> t1(BlockedRateQueryParamDto dto) {
58
+        initDefaultDateRange(dto);
59
+        List<Date> dateList = getDateList(dto);
60
+        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
61
+        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
62
+        List<BlockedRateScreenT1Dto> result = new ArrayList<>();
63
+        dateList.forEach(date -> {
64
+            BlockedRateScreenT1Dto dtoItem = new BlockedRateScreenT1Dto();
65
+            dtoItem.setStatDate(date);
66
+            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
67
+            dtoItem.setT1AAreaRatePeak(calculateAvg(dateData, BlockedRate::getT1AAreaRatePeak));
68
+            dtoItem.setT1BAreaRatePeak(calculateAvg(dateData, BlockedRate::getT1BAreaRatePeak));
69
+            result.add(dtoItem);
70
+        });
71
+        return result;
72
+    }
73
+
74
+    /**
75
+     * T2速率统计数据
76
+     *
77
+     * @param dto 上行参数
78
+     * @return 结果
79
+     */
80
+    @Override
81
+    public List<BlockedRateScreenT2Dto> t2(BlockedRateQueryParamDto dto) {
82
+        initDefaultDateRange(dto);
83
+        List<Date> dateList = getDateList(dto);
84
+        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
85
+        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
86
+        List<BlockedRateScreenT2Dto> result = new ArrayList<>();
87
+        dateList.forEach(date -> {
88
+            BlockedRateScreenT2Dto dtoItem = new BlockedRateScreenT2Dto();
89
+            dtoItem.setStatDate(date);
90
+            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
91
+            dtoItem.setT2DomesticRatePeak(calculateAvg(dateData, BlockedRate::getT2DomesticRatePeak));
92
+            dtoItem.setT2InternationalRatePeak(calculateAvg(dateData, BlockedRate::getT2InternationalRatePeak));
93
+            result.add(dtoItem);
94
+        });
95
+        return result;
96
+    }
97
+
98
+    /**
99
+     * 国内速率统计数据
100
+     *
101
+     * @param dto 上行参数
102
+     * @return 结果
103
+     */
104
+    @Override
105
+    public List<BlockedRateScreenBrigadeDto> domestic(BlockedRateQueryParamDto dto) {
106
+        initDefaultDateRange(dto);
107
+        List<Date> dateList = getDateList(dto);
108
+        List<SysDept> targetDeptList = getTargetDeptList(dto);
109
+        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
110
+        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
111
+        List<BlockedRateScreenBrigadeDto> result = new ArrayList<>();
112
+        dateList.forEach(date -> {
113
+            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
114
+            targetDeptList.forEach(dept -> {
115
+                BlockedRateScreenBrigadeDto dtoItem = new BlockedRateScreenBrigadeDto();
116
+                dtoItem.setStatDate(date);
117
+                dtoItem.setDutyBrigadeId(dept.getDeptId());
118
+                dtoItem.setDutyBrigadeName(dept.getDeptName());
119
+                List<BlockedRate> deptData = dateData.stream()
120
+                        .filter(rate -> dept.getDeptId().equals(rate.getDutyBrigadeId()))
121
+                        .collect(Collectors.toList());
122
+                dtoItem.setAvgRatePeak(calculateAvg(deptData, BlockedRate::getTravelInspectionDomesticAvgRatePeak));
123
+                result.add(dtoItem);
124
+            });
125
+        });
126
+        return result;
127
+    }
128
+
129
+    /**
130
+     * 国际速率统计数据
131
+     *
132
+     * @param dto 上行参数
133
+     * @return 结果
134
+     */
135
+    @Override
136
+    public List<BlockedRateScreenBrigadeDto> international(BlockedRateQueryParamDto dto) {
137
+        initDefaultDateRange(dto);
138
+        List<Date> dateList = getDateList(dto);
139
+        List<SysDept> targetDeptList = getTargetDeptList(dto);
140
+        List<BlockedRate> blockedRateList = queryBlockedRateList(dto);
141
+        Map<Date, List<BlockedRate>> dateGroupMap = groupByDate(blockedRateList);
142
+        List<BlockedRateScreenBrigadeDto> result = new ArrayList<>();
143
+        dateList.forEach(date -> {
144
+            List<BlockedRate> dateData = dateGroupMap.getOrDefault(date, Collections.emptyList());
145
+            targetDeptList.forEach(dept -> {
146
+                BlockedRateScreenBrigadeDto dtoItem = new BlockedRateScreenBrigadeDto();
147
+                dtoItem.setStatDate(date);
148
+                dtoItem.setDutyBrigadeId(dept.getDeptId());
149
+                dtoItem.setDutyBrigadeName(dept.getDeptName());
150
+                List<BlockedRate> deptData = dateData.stream()
151
+                        .filter(rate -> dept.getDeptId().equals(rate.getDutyBrigadeId()))
152
+                        .collect(Collectors.toList());
153
+                dtoItem.setAvgRatePeak(calculateAvg(deptData, BlockedRate::getInternationalTransferAvgRatePeak));
154
+                result.add(dtoItem);
155
+            });
156
+        });
157
+        return result;
158
+    }
159
+
160
+    /**
161
+     * 初始化默认日期范围
162
+     *
163
+     * @param dto 上行参数
164
+     */
165
+    private void initDefaultDateRange(BlockedRateQueryParamDto dto) {
166
+        if (dto.getSpecifiedDate() == null && dto.getStartDate() == null && dto.getEndDate() == null) {
167
+            dto.setStartDate(BlockedDateUtils.getFirstDayOfYear());
168
+            dto.setEndDate(BlockedDateUtils.getCurrentDate());
169
+        }
170
+    }
171
+
172
+    /**
173
+     * 获取指定日期列表
174
+     *
175
+     * @param dto 上行参数
176
+     * @return 日期列表
177
+     */
178
+    private List<Date> getDateList(BlockedRateQueryParamDto dto) {
179
+        if (dto.getSpecifiedDate() != null) {
180
+            return Collections.singletonList(dto.getSpecifiedDate());
181
+        }
182
+        return BlockedDateUtils.generateDateList(dto.getStartDate(), dto.getEndDate());
183
+    }
184
+
185
+    /**
186
+     * 查询数据
187
+     *
188
+     * @param dto 上行参数
189
+     * @return 列表
190
+     */
191
+    private List<BlockedRate> queryBlockedRateList(BlockedRateQueryParamDto dto) {
192
+        BlockedRate query = new BlockedRate();
193
+        query.setStatDate(dto.getSpecifiedDate());
194
+        query.setStartDate(dto.getStartDate());
195
+        query.setEndDate(dto.getEndDate());
196
+        query.setDutyBrigadeId(dto.getBrigadeId());
197
+        query.setDutyBrigadeName(dto.getBrigadeName());
198
+        return blockedRateMapper.selectBlockedRateList(query);
199
+    }
200
+
201
+    /**
202
+     * 按日期分组
203
+     *
204
+     * @param blockedRateList 数据列表
205
+     * @return 分组结果
206
+     */
207
+    private Map<Date, List<BlockedRate>> groupByDate(List<BlockedRate> blockedRateList) {
208
+        return blockedRateList.stream()
209
+                .filter(rate -> rate.getStatDate() != null)
210
+                .collect(Collectors.groupingBy(BlockedRate::getStatDate));
211
+    }
212
+
213
+    /**
214
+     * 计算平均值
215
+     *
216
+     * @param dataList        数据列表
217
+     * @param valueExtractor  值提取器
218
+     * @return 平均值
219
+     */
220
+    private BigDecimal calculateAvg(List<BlockedRate> dataList, java.util.function.Function<BlockedRate, BigDecimal> valueExtractor) {
221
+        List<BigDecimal> values = dataList.stream()
222
+                .map(valueExtractor)
223
+                .filter(val -> val != null && val.compareTo(BigDecimal.ZERO) != 0)
224
+                .collect(Collectors.toList());
225
+        if (values.isEmpty()) {
226
+            return BigDecimal.ZERO;
227
+        }
228
+        BigDecimal sum = values.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
229
+        return sum.divide(BigDecimal.valueOf(values.size()), SCALE, ROUNDING_MODE);
230
+    }
231
+
232
+    /**
233
+     * 获取指定部门列表
234
+     *
235
+     * @param dto 上行参数
236
+     * @return 部门列表
237
+     */
238
+    private List<SysDept> getTargetDeptList(BlockedRateQueryParamDto dto) {
239
+        if (dto.getBrigadeId() == null) {
240
+            List<SysDept> deptListAll = sysDeptService.selectDeptInfoAll(new SysDept());
241
+            return deptListAll.stream()
242
+                    .filter(dept -> BRIGADE_NAMES.contains(dept.getDeptName()))
243
+                    .collect(Collectors.toList());
244
+        } else {
245
+            return sysDeptService.selectDeptByIdList(Collections.singletonList(dto.getBrigadeId()));
246
+        }
247
+    }
248
+
249
+}

+ 7 - 0
airport-blocked/src/main/resources/mapper/blocked/BlockedRateScreenMapper.xml

@@ -0,0 +1,7 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.sundot.airport.blocked.mapper.BlockedRateScreenMapper">
6
+
7
+</mapper>

+ 41 - 0
airport-common/src/main/java/com/sundot/airport/common/core/domain/BaseScreenQueryParamDto.java

@@ -0,0 +1,41 @@
1
+package com.sundot.airport.common.core.domain;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import lombok.Data;
5
+import org.springframework.format.annotation.DateTimeFormat;
6
+
7
+import java.io.Serializable;
8
+import java.util.Date;
9
+
10
+/**
11
+ * 大屏查询基础参数
12
+ *
13
+ * @author ruoyi
14
+ */
15
+@Data
16
+public class BaseScreenQueryParamDto implements Serializable {
17
+
18
+    private static final long serialVersionUID = 1L;
19
+
20
+    /**
21
+     * 指定日期
22
+     */
23
+    @JsonFormat(pattern = "yyyy-MM-dd")
24
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
25
+    private Date specifiedDate;
26
+
27
+    /**
28
+     * 开始日期
29
+     */
30
+    @JsonFormat(pattern = "yyyy-MM-dd")
31
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
32
+    private Date startDate;
33
+
34
+    /**
35
+     * 结束日期
36
+     */
37
+    @JsonFormat(pattern = "yyyy-MM-dd")
38
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
39
+    private Date endDate;
40
+
41
+}

+ 23 - 0
airport-common/src/main/java/com/sundot/airport/common/core/domain/BlockedRateQueryParamDto.java

@@ -0,0 +1,23 @@
1
+package com.sundot.airport.common.core.domain;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * 速率查询参数
7
+ *
8
+ * @author ruoyi
9
+ */
10
+@Data
11
+public class BlockedRateQueryParamDto extends BaseScreenQueryParamDto {
12
+
13
+    /**
14
+     * 大队ID
15
+     */
16
+    private Long brigadeId;
17
+
18
+    /**
19
+     * 大队名称
20
+     */
21
+    private String brigadeName;
22
+
23
+}

+ 81 - 0
airport-common/src/main/java/com/sundot/airport/common/utils/BlockedDateUtils.java

@@ -0,0 +1,81 @@
1
+package com.sundot.airport.common.utils;
2
+
3
+import java.util.ArrayList;
4
+import java.util.Calendar;
5
+import java.util.Date;
6
+import java.util.List;
7
+
8
+/**
9
+ * 日期工具类
10
+ */
11
+public class BlockedDateUtils {
12
+
13
+    /**
14
+     * 生成从开始日期到结束日期(含)的所有日期列表(时间部分为00:00:00)
15
+     * @param startDate 开始日期
16
+     * @param endDate 结束日期
17
+     * @return 日期列表(按升序排列)
18
+     */
19
+    public static List<Date> generateDateList(Date startDate, Date endDate) {
20
+        List<Date> dateList = new ArrayList<>();
21
+        if (startDate == null || endDate == null || startDate.after(endDate)) {
22
+            return dateList; // 无效输入返回空列表
23
+        }
24
+
25
+        // 创建Calendar实例并标准化时间
26
+        Calendar startCal = Calendar.getInstance();
27
+        startCal.setTime(startDate);
28
+        setTimeToMidnight(startCal);
29
+
30
+        Calendar endCal = Calendar.getInstance();
31
+        endCal.setTime(endDate);
32
+        setTimeToMidnight(endCal);
33
+
34
+        // 遍历日期范围
35
+        while (!startCal.after(endCal)) {
36
+            dateList.add(startCal.getTime()); // 添加当前日期
37
+            startCal.add(Calendar.DAY_OF_MONTH, 1); // 增加一天
38
+        }
39
+        return dateList;
40
+    }
41
+
42
+    /**
43
+     * 将Calendar的时间部分设置为00:00:00.000
44
+     */
45
+    private static void setTimeToMidnight(Calendar calendar) {
46
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
47
+        calendar.set(Calendar.MINUTE, 0);
48
+        calendar.set(Calendar.SECOND, 0);
49
+        calendar.set(Calendar.MILLISECOND, 0);
50
+    }
51
+
52
+    /**
53
+     *  当前日期(时间部分为 00:00:00)
54
+     */
55
+    public static Date getCurrentDate() {
56
+        Calendar cal = Calendar.getInstance();
57
+        resetTimeFields(cal);
58
+        return cal.getTime();
59
+    }
60
+
61
+    /**
62
+     *  本年度 1 月 1 日(时间部分为 00:00:00)
63
+     */
64
+    public static Date getFirstDayOfYear() {
65
+        Calendar cal = Calendar.getInstance();
66
+        cal.set(Calendar.DAY_OF_YEAR, 1);  // 设置为当年第一天
67
+        resetTimeFields(cal);
68
+        return cal.getTime();
69
+    }
70
+
71
+    /**
72
+     * 重置Calendar的时间字段(秒毫秒)
73
+     */
74
+    private static void resetTimeFields(Calendar cal) {
75
+        cal.set(Calendar.HOUR_OF_DAY, 0);
76
+        cal.set(Calendar.MINUTE, 0);
77
+        cal.set(Calendar.SECOND, 0);
78
+        cal.set(Calendar.MILLISECOND, 0);
79
+    }
80
+
81
+}