吉安感知网项目-后端
xiebin
2026-01-06 d207a86cdf1ab52ef8cb7cd83bad8fceab8038cf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
package org.sxkj.common.utils;
 
import org.apache.commons.lang.StringUtils;
import org.sxkj.common.enums.DateEnum;
 
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Consumer;
 
public class XAxisDataInitializer {
 
    /**
     * 根据时间范围枚举初始化X轴数据(截止当前时间点)
     *
     * @param timeRange 时间范围枚举
     * @return X轴标签列表
     */
    public static List<String> initXAxisDataToNow(DateEnum timeRange) {
        if (Objects.isNull(timeRange)) {
            return Collections.emptyList();
        }
        switch (timeRange) {
            case TODAY:
                return initTodayXAxisToNow(null);
            case CURRENT_WEEK:
                return initCurrentWeekXAxisToNow();
            case CURRENT_MONTH:
                return initCurrentMonthXAxisToNow(null);
            case CURRENT_YEAR:
                return initCurrentYearXAxisToNow(timeRange.getEndDate());
            case INTERVAL_TIME:
                return initIntervalTime(timeRange);
            case YEARS:
                return initYears(timeRange);
            case MONTHS:
                return initMonths(timeRange);
            case DAYS:
                return initDays(timeRange);
            default:
                throw new IllegalArgumentException("未知的时间范围类型");
        }
    }
 
 
    /**
     * 根据枚举与日期获取时间
     *
     * @param timeRange 枚举
     * @param startDate 开始时间
     * @return 时间段
     */
    public static List<String> initXAxisDataByStartTime(DateEnum timeRange, LocalDateTime startDate) {
        if (Objects.isNull(timeRange)) {
            return Collections.emptyList();
        }
        switch (timeRange) {
            case DAY:
                return initTodayXAxisToNow(startDate);
            case MONTH:
                return initCurrentMonthXAxisToNow(startDate);
            case YEAR:
                return initCurrentYearXAxisToNow(startDate);
            default:
                throw new IllegalArgumentException("未知的时间范围类型");
        }
    }
 
    /**
     * 根据枚举与日期获取时间
     *
     * @param timeRange 枚举
     * @param startDate 开始时间
     * @return 时间段
     */
    public static List<String> initXAxisDataByStartTimeTwo(DateEnum timeRange, LocalDateTime startDate, LocalDateTime endDate) {
        if (Objects.isNull(timeRange)) {
            return Collections.emptyList();
        }
        switch (timeRange) {
            case DAY:
                return initTodayXAxisToNow(startDate, endDate);
            case MONTH:
                return initCurrentMonthXAxisToNow(startDate, endDate);
            case YEAR:
                return initCurrentYearXAxisToNow(startDate, endDate);
            default:
                throw new IllegalArgumentException("未知的时间范围类型");
        }
    }
 
 
    /**
     * 间隔时间内数据
     *
     * @param timeRange
     * @return
     */
    private static List<String> initIntervalTime(DateEnum timeRange) {
        LocalDateTime startDate = timeRange.getStartDate();
        LocalDateTime endDate = timeRange.getEndDate();
        List<MonthDay> monthDaysBetween = getMonthDaysBetween(startDate, endDate);
        List<String> days = new ArrayList<>();
        for (int i = 0; i < monthDaysBetween.size(); i++) {
            MonthDay monthDay = monthDaysBetween.get(i);
            days.add(String.format("%02d", monthDay.getMonth().getValue()) + "-" + String.format("%02d", monthDay.getDayOfMonth()));
        }
        return days;
    }
 
    /**
     * 年份数据
     *
     * @param timeRange
     * @return
     */
    private static List<String> initYears(DateEnum timeRange) {
        LocalDateTime startDate = timeRange.getStartDate();
        LocalDateTime endDate = timeRange.getEndDate();
        List<String> years = new ArrayList<>();
        // 确保开始日期不晚于结束日期
        if (startDate.isAfter(endDate)) {
            return years;
        }
 
        int startYear = startDate.getYear();
        int endYear = endDate.getYear();
 
        // 如果同一年,直接返回该年份
        if (startYear == endYear) {
            years.add(startYear + "");
        } else {
            // 跨年份的情况,添加从开始年份到结束年份之间的所有年份
            for (int year = startYear; year <= endYear; year++) {
                years.add(year + "");
            }
        }
 
        return years;
    }
 
    /**
     * 获取指定时间范围内的所有月份(支持跨年)
     *
     * @param timeRange 时间范围枚举
     * @return 月份字符串列表,格式为 "yyyy-MM"
     */
    public static List<String> initMonths(DateEnum timeRange) {
        LocalDateTime startDate = timeRange.getStartDate();
        LocalDateTime endDate = timeRange.getEndDate();
        List<String> months = new ArrayList<>();
 
        if (startDate == null || endDate == null || startDate.isAfter(endDate)) {
            // 空或非法时间范围返回空列表
            return months;
        }
 
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
 
        // 对齐到月初
        LocalDateTime current = startDate.withDayOfMonth(1).withHour(0).withSecond(0).withMinute(0);
        LocalDateTime endMonthStart = endDate.withDayOfMonth(1).withHour(0).withSecond(0).withMinute(0);
 
        while (!current.isAfter(endMonthStart)) {
            months.add(current.format(formatter));
            current = current.plusMonths(1);
        }
 
        return months;
    }
 
    /**
     * 获取指定时间范围内的所有天(支持跨月)
     *
     * @param timeRange 时间范围枚举
     * @return 月份字符串列表,格式为 "mm-dd"
     */
    public static List<String> initDays(DateEnum timeRange) {
        LocalDateTime startDate = timeRange.getStartDate();
        LocalDateTime endDate = timeRange.getEndDate();
        List<String> days = new ArrayList<>();
 
        if (startDate == null || endDate == null || startDate.isAfter(endDate)) {
            // 空或非法时间范围返回空列表
            return days;
        }
 
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
 
        // 设置为当天的最小时间
        LocalDateTime current = startDate.with(LocalTime.MIN);
        while (!current.isAfter(endDate)) {
            days.add(current.format(formatter));
            current = current.plusDays(1);
        }
 
        return days;
    }
 
    public static List<MonthDay> getMonthDaysBetween(LocalDateTime startDate, LocalDateTime endDate) {
        List<MonthDay> monthDays = new ArrayList<>();
 
        // 确保开始日期不晚于结束日期
        if (startDate.isAfter(endDate)) {
            return monthDays;
        }
 
        // 获取开始和结束的MonthDay
        MonthDay start = MonthDay.from(startDate);
        MonthDay end = MonthDay.from(endDate);
 
        // 如果同一年,直接比较
        if (startDate.getYear() == endDate.getYear()) {
            LocalDateTime current = startDate;
            while (!current.isAfter(endDate)) {
                monthDays.add(MonthDay.from(current));
                current = current.plusDays(1);
            }
        } else {
            // 跨年份的情况
 
            // 添加从开始日期到年底的所有月日
            LocalDateTime current = startDate;
            while (current.getYear() == startDate.getYear()) {
                monthDays.add(MonthDay.from(current));
                current = current.plusDays(1);
            }
 
            // 添加中间完整年份的所有可能月日(2月29日需要特殊处理)
            // 这里可以根据需求决定是否包含2月29日
 
            // 添加从年初到结束日期的所有月日
            current = endDate.withDayOfYear(1);
            while (!current.isAfter(endDate)) {
                MonthDay md = MonthDay.from(current);
                if (!monthDays.contains(md)) {
                    monthDays.add(md);
                }
                current = current.plusDays(1);
            }
        }
 
        return monthDays;
    }
 
    // 初始化今日X轴数据 (0时-当前小时)
    private static List<String> initTodayXAxisToNow(LocalDateTime startDate) {
        LocalDateTime now = Optional.ofNullable(startDate).orElse(LocalDateTime.now());
        // 设置当天的结束时间为23:59:59
        int currentHour = now.with(LocalTime.MAX).getHour();
        List<String> hours = new ArrayList<>();
        for (int i = 0; i <= currentHour; i++) {
            hours.add(String.format("%02d", i) + "");
        }
        return hours;
    }
 
 
    // 初始化本周X轴数据 (周一到当前星期几 是多少号到多少号)
    private static List<String> initCurrentWeekXAxisToNow() {
        LocalDate today = LocalDate.now();
        LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDate endOfWeek = today;
 
        List<String> days = new ArrayList<>();
        LocalDate currentDay = startOfWeek;
 
        while (!currentDay.isAfter(endOfWeek)) {
            days.add(String.format("%02d", currentDay.getDayOfMonth()) + "");
            currentDay = currentDay.plusDays(1);
        }
 
        return days;
    }
 
    // 初始化当月X轴数据 (1日-当前日期)
    private static List<String> initCurrentMonthXAxisToNow(LocalDateTime startDate) {
        LocalDateTime endDay = Objects.nonNull(startDate) ? startDate.with(TemporalAdjusters.lastDayOfMonth()) : LocalDateTime.now();
 
        int currentDayOfMonth = endDay.getDayOfMonth();
        int currentMonth = endDay.getMonthValue();
        List<String> days = new ArrayList<>();
        for (int i = 1; i <= currentDayOfMonth; i++) {
            days.add(String.format("%02d", currentMonth) + "-" + String.format("%02d", i));
        }
        return days;
    }
 
    // 初始化本年X轴数据 (1月-当前月份)
    private static List<String> initCurrentYearXAxisToNow(LocalDateTime startDate) {
        LocalDateTime endDay = getProcessedDateTime(startDate);
        int currentMonth = endDay.getMonthValue();
        List<String> months = new ArrayList<>();
        for (int i = 1; i <= currentMonth; i++) {
            months.add(String.format("%02d", i) + "");
        }
        return months;
    }
 
 
    // 初始化今日X轴数据
    private static List<String> initTodayXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) {
 
        if (startDate == null || endDate == null || startDate.isAfter(endDate)) {
            return Collections.emptyList();
        }
 
        // 判断是否跨年
        boolean isCrossYear = startDate.getYear() != endDate.getYear();
 
        DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("dd");
        DateTimeFormatter monthDayFormatter = DateTimeFormatter.ofPattern("MM-dd");
        DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
        List<String> xAxisData = new ArrayList<>();
        LocalDateTime current = startDate.with(LocalTime.MIN);
        // 判断开始时间和结束时间是否同一个月
        boolean isSameMonth = startDate.getMonth() != endDate.getMonth();
 
        while (!current.isAfter(endDate)) {
            if (isCrossYear) {
                xAxisData.add(current.format(fullFormatter));
            } else if (isSameMonth) {
                xAxisData.add(current.format(monthDayFormatter));
            } else {
                xAxisData.add(current.format(dayFormatter));
            }
            current = current.plusDays(1);
        }
 
        return xAxisData;
    }
 
 
    // 初始化当月X轴数据 (1日-当前日期)
    private static List<String> initCurrentMonthXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) {
        List<String> result = new ArrayList<>();
        boolean isCrossYear = startDate.getYear() != endDate.getYear();
 
        DateTimeFormatter formatter = isCrossYear
            ? DateTimeFormatter.ofPattern("yyyy-MM")
            : DateTimeFormatter.ofPattern("MM");
 
        LocalDateTime current = startDate.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime endMonthStart = endDate.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
 
        while (!current.isAfter(endMonthStart)) {
            result.add(current.format(formatter));
            current = current.plusMonths(1);
        }
 
        return result;
    }
 
    // 初始化本年X轴数据 (1月-当前月份)
    private static List<String> initCurrentYearXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) {
        List<String> result = new ArrayList<>();
 
        // 获取当前年份
        int currentYear = LocalDateTime.now().getYear();
 
        // 处理起始时间:若为空或小于2023,则从2023年开始
        int startYear = 2023;
        if (startDate != null && startDate.getYear() >= 2023) {
            startYear = startDate.getYear();
        }
 
        // 处理结束时间:若为空或大于当前年,则取当前年
        int endYear = currentYear;
        if (startDate != null && startDate.getYear() < currentYear) {
            endYear = endDate.getYear();
        }
 
        // 填充年份列表
        for (int year = startYear; year <= endYear; year++) {
            result.add(String.valueOf(year));
        }
 
        return result;
    }
 
 
 
    public static LocalDateTime getProcessedDateTime(LocalDateTime input) {
        LocalDateTime now = LocalDateTime.now();
        int currentYear = now.getYear();
 
        // 如果输入为空,返回今年到当前月份
        if (input == null) {
            return now;
        }
 
        int inputYear = input.getYear();
 
        // 如果输入年份是今年,返回当前时间
//        if (inputYear == currentYear) {
//            return now;
//        }
//        // 如果输入年份不是今年,返回该年最后一天最后一刻
//        else {
            return LocalDateTime.of(inputYear, Month.DECEMBER, 31, 23, 59, 59);
//        }
    }
 
//    public static void main(String[] args) {
//        // 测试用例
//        System.out.println("输入2024年: " + getProcessedDateTime(LocalDateTime.of(2024, 1, 1, 0, 0)));
//        System.out.println("输入2025年(今年): " + getProcessedDateTime(LocalDateTime.of(2025, 1, 1, 0, 0)));
//        System.out.println("输入为空: " + getProcessedDateTime(null));
//    }
 
 
    /**
     * 设置dateEnum 每根柱子上对应的时间数据
     *
     * @param dateEnum     事件枚举
     * @param chartIndex   从0 开始第几根柱子
     * @param setStartTime 设置开始时间
     * @param setEndTime   设置结束时间
     */
    public static void settingBarIndexDateValue(DateEnum dateEnum,
                                                Integer chartIndex,
                                                Consumer<LocalDateTime> setStartTime,
                                                Consumer<LocalDateTime> setEndTime) {
        if (Objects.isNull(dateEnum) ||
            Objects.isNull(chartIndex) ||
            Objects.isNull(setStartTime) ||
            Objects.isNull(setEndTime)) {
            return;
        }
        List<String> xAxisDataToNow = XAxisDataInitializer.initXAxisDataToNow(dateEnum);
        LocalDateTime now = LocalDateTime.now();
        ValidUtil.assertIf(xAxisDataToNow.size() <= chartIndex, "传参有误");
        String dateStr = xAxisDataToNow.get(chartIndex);
        if (StringUtils.isEmpty(dateStr)) {
            return;
        }
        LocalDateTime start = null;
        LocalDateTime end = null;
        switch (dateEnum) {
            case TODAY: {
                start = now.withHour(Integer.parseInt(dateStr));
                end = now.withHour(Integer.parseInt(dateStr));
            }
            break;
            case CURRENT_WEEK: {
                now = now.withDayOfMonth(Integer.parseInt(dateStr)).withHour(0);
                start = now.withHour(0);
                end = now.withHour(23);
            }
            break;
            case CURRENT_MONTH: {
                String[] split = dateStr.split("-");
                now = now.with(TemporalAdjusters.firstDayOfMonth());
                LocalDateTime localDateTime = now.withDayOfMonth(Integer.parseInt(split[1]));
                start = localDateTime.withHour(0);
                end = localDateTime.withHour(23);
            }
            break;
            case CURRENT_YEAR: {
                LocalDateTime firstMonthOfYear = LocalDateTime.now()
                    .withMonth(Integer.parseInt(dateStr));
                start = firstMonthOfYear.withDayOfMonth(1).withHour(0);
                end = firstMonthOfYear.with(TemporalAdjusters.lastDayOfMonth()).withHour(23);
 
            }
            break;
        }
        ;
        //开始时间 结束时间设置
        setStartTime.accept(start.withMinute(0).withSecond(0).withNano(0));
        setEndTime.accept(end.withMinute(59).withSecond(59).withNano(0));
    }
 
    /**
     * 获取开始与结束时间内 格式化的时间数据
     *
     * @param startDate  开始时间
     * @param endDate    结束时间
     * @param formatTime 格式化时间 字符串
     * @return 格式化时间列表
     */
 
    public static List<String> getFormatTimeByDate(LocalDateTime startDate,
                                                   LocalDateTime endDate,
                                                   String formatTime) {
        List<String> formattedDates = new ArrayList<>();
 
        if (startDate == null || endDate == null || formatTime == null) {
            return Collections.emptyList();
        }
 
        // 如果开始时间晚于结束时间,交换它们
        if (startDate.isAfter(endDate)) {
            LocalDateTime temp = startDate;
            startDate = endDate;
            endDate = temp;
        }
 
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatTime);
        // 添加开始时间
        formattedDates.add(startDate.format(formatter));
        // 如果开始和结束时间相同,直接返回
        if (startDate.isEqual(endDate)) {
            return formattedDates;
        }
        // 按天递增,直到达到结束时间
        LocalDateTime current = startDate.plusDays(1);
        while (!current.isAfter(endDate)) {
            formattedDates.add(current.format(formatter));
            current = current.plusDays(1);
        }
 
        return formattedDates;
    }
 
 
}