Commit 9ef9a3d0a8ea581d4673ef152a0fc65ab946f7b9
1 parent
5c63a885
养护计划提交
Showing
7 changed files
with
96 additions
and
57 deletions
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/inspectionplan/vo/InspectionPlanDetailRespVO.java
| ... | ... | @@ -52,6 +52,14 @@ public class InspectionPlanDetailRespVO { |
| 52 | 52 | @ExcelProperty("执行时间") |
| 53 | 53 | private LocalDateTime endTime; |
| 54 | 54 | |
| 55 | + @Schema(description = "计划次数") | |
| 56 | + @ExcelProperty("计划次数") | |
| 57 | + private Integer planNum; | |
| 58 | + | |
| 59 | + @Schema(description = "完成次数") | |
| 60 | + @ExcelProperty("完成次数") | |
| 61 | + private Integer planFinishNum; | |
| 62 | + | |
| 55 | 63 | @Schema(description = "完成状态 1:未完成;2:进行中;3:已完成", requiredMode = Schema.RequiredMode.REQUIRED) |
| 56 | 64 | @ExcelProperty("完成状态 1:未完成;2:进行中;3:已完成") |
| 57 | 65 | private Integer finishState; | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/maintainplan/vo/MaintainPlanDetailRespVO.java
| ... | ... | @@ -51,6 +51,10 @@ public class MaintainPlanDetailRespVO { |
| 51 | 51 | @ExcelProperty("执行时间") |
| 52 | 52 | private LocalDateTime endTime; |
| 53 | 53 | |
| 54 | + @Schema(description = "计划次数") | |
| 55 | + @ExcelProperty("计划次数") | |
| 56 | + private Integer planNum; | |
| 57 | + | |
| 54 | 58 | @Schema(description = "完成百分比", requiredMode = Schema.RequiredMode.REQUIRED) |
| 55 | 59 | @ExcelProperty("完成百分比") |
| 56 | 60 | private Double finishPercent; | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/inspectionplan/InspectionPlanDetailDO.java
| ... | ... | @@ -57,6 +57,15 @@ public class InspectionPlanDetailDO extends BaseDO { |
| 57 | 57 | * 排序号:第n次计划 |
| 58 | 58 | */ |
| 59 | 59 | private Integer sortNum; |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 计划次数 | |
| 63 | + */ | |
| 64 | + private Integer planNum; | |
| 65 | + /** | |
| 66 | + * 已完成次数 | |
| 67 | + */ | |
| 68 | + private Integer planFinishNum; | |
| 60 | 69 | /** |
| 61 | 70 | * 执行开始时间 |
| 62 | 71 | */ | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/maintainplan/MaintainPlanDetailDO.java
| ... | ... | @@ -55,6 +55,7 @@ public class MaintainPlanDetailDO extends BaseDO { |
| 55 | 55 | * 排序号:第n次计划 |
| 56 | 56 | */ |
| 57 | 57 | private Integer sortNum; |
| 58 | + | |
| 58 | 59 | /** |
| 59 | 60 | * 执行开始时间 |
| 60 | 61 | */ |
| ... | ... | @@ -63,6 +64,12 @@ public class MaintainPlanDetailDO extends BaseDO { |
| 63 | 64 | * 执行时间 |
| 64 | 65 | */ |
| 65 | 66 | private LocalDateTime endTime; |
| 67 | + | |
| 68 | + /** | |
| 69 | + * 计划次数 | |
| 70 | + */ | |
| 71 | + private Integer planNum; | |
| 72 | + | |
| 66 | 73 | /** |
| 67 | 74 | * 完成百分比 |
| 68 | 75 | */ | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/inspectionplan/InspectionPlanServiceImpl.java
| ... | ... | @@ -90,10 +90,9 @@ public class InspectionPlanServiceImpl implements InspectionPlanService { |
| 90 | 90 | log.warn("获取两个时间之间间隔天数错误"); |
| 91 | 91 | return CommonResult.error(INSPECTION_CYCLE_ERROR); |
| 92 | 92 | } |
| 93 | - //计算计划次数 | |
| 94 | - Integer planNum = calculate.size(); | |
| 95 | - | |
| 96 | 93 | |
| 94 | + //计算计划次数 | |
| 95 | + int planNum = calculate.stream().mapToInt(PeriodResult::getCount).sum(); | |
| 97 | 96 | //巡检计划list |
| 98 | 97 | List<InspectionPlanDO> inspectionPlanList = new ArrayList<>(); |
| 99 | 98 | //角色列表 |
| ... | ... | @@ -138,13 +137,16 @@ public class InspectionPlanServiceImpl implements InspectionPlanService { |
| 138 | 137 | roleList.add(inspectionPlanRoleDO); |
| 139 | 138 | }); |
| 140 | 139 | /*3.插入巡查计划明细*/ |
| 140 | + int index = 1; | |
| 141 | 141 | for (PeriodResult periodResult : calculate) { |
| 142 | 142 | InspectionPlanDetailDO entity = getInspectionPlanDetailDO(batchNo, createReqVO, roadReqVO, now); |
| 143 | 143 | ThreadUtil.sleep(2); |
| 144 | - entity.setSortNum(periodResult.getCount()); | |
| 144 | + entity.setSortNum(index); | |
| 145 | + entity.setPlanNum(periodResult.getCount()); | |
| 145 | 146 | entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| 146 | 147 | entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| 147 | 148 | detailDOList.add(entity); |
| 149 | + index++; | |
| 148 | 150 | } |
| 149 | 151 | }); |
| 150 | 152 | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/maintainplan/MaintainPlanServiceImpl.java
| ... | ... | @@ -93,7 +93,7 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { |
| 93 | 93 | return CommonResult.error(INSPECTION_CYCLE_ERROR); |
| 94 | 94 | } |
| 95 | 95 | //计算计划次数 |
| 96 | - Integer planNum = calculate.size(); | |
| 96 | + int planNum = calculate.stream().mapToInt(PeriodResult::getCount).sum(); | |
| 97 | 97 | //巡检计划list |
| 98 | 98 | List<MaintainPlanDO> maintainPlanList = new ArrayList<>(); |
| 99 | 99 | //角色列表 |
| ... | ... | @@ -138,13 +138,16 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { |
| 138 | 138 | roleList.add(maintainPlanRoleDO); |
| 139 | 139 | }); |
| 140 | 140 | /*3.插入巡查计划明细*/ |
| 141 | + int index =1; | |
| 141 | 142 | for (PeriodResult periodResult : calculate) { |
| 142 | 143 | MaintainPlanDetailDO entity = getMaintainPlanDetailDO(batchNo, createReqVO, roadReqVO, now); |
| 143 | 144 | ThreadUtil.sleep(2); |
| 144 | - entity.setSortNum(periodResult.getCount()); | |
| 145 | + entity.setSortNum(index); | |
| 146 | + entity.setPlanNum(periodResult.getCount()); | |
| 145 | 147 | entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| 146 | 148 | entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| 147 | 149 | detailDOList.add(entity); |
| 150 | + index++; | |
| 148 | 151 | } |
| 149 | 152 | }); |
| 150 | 153 | ... | ... |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/util/timeinterval/TimeIntervalFrequencyUtil.java
| ... | ... | @@ -11,7 +11,7 @@ import static com.zteits.urbanops.module.garden.enums.ErrorCodeConstants.INSPECT |
| 11 | 11 | |
| 12 | 12 | /** |
| 13 | 13 | * 时间区间拆分+频次计算工具类 |
| 14 | - * 支持:按日/周/月/年拆分,区间临界点重叠,动态计算每个区间的执行频次 | |
| 14 | + * 支持:按日/周/月/年拆分,基于固定天数换算(周=7天,月=30天,年=365天) | |
| 15 | 15 | */ |
| 16 | 16 | public class TimeIntervalFrequencyUtil { |
| 17 | 17 | |
| ... | ... | @@ -42,12 +42,12 @@ public class TimeIntervalFrequencyUtil { |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | 44 | /** |
| 45 | - * 计算时间段划分结果 | |
| 45 | + * 计算时间段划分结果(基于固定天数换算) | |
| 46 | 46 | * |
| 47 | 47 | * @param startStr 开始日期 (yyyy-MM-dd) |
| 48 | 48 | * @param endStr 结束日期 (yyyy-MM-dd) |
| 49 | 49 | * @param freq 频次值,格式 "x/y" |
| 50 | - * @param cycleId cycleId 1:日/次;2:周/次;3:月/次;4:年/次 | |
| 50 | + * @param cycleId 1:日/次;2:周/次;3:月/次;4:年/次 | |
| 51 | 51 | * @return 划分结果列表 |
| 52 | 52 | */ |
| 53 | 53 | public static List<PeriodResult> calculate(String startStr, String endStr, String freq, Integer cycleId) { |
| ... | ... | @@ -62,31 +62,29 @@ public class TimeIntervalFrequencyUtil { |
| 62 | 62 | if (parts.length != 2) { |
| 63 | 63 | throw new IllegalArgumentException("频次值格式错误,应为 'x/y': " + freq); |
| 64 | 64 | } |
| 65 | - int x = Integer.parseInt(parts[0]); | |
| 66 | - int y = Integer.parseInt(parts[1]); | |
| 65 | + int x = Integer.parseInt(parts[0]); // 每周期次数 | |
| 66 | + int y = Integer.parseInt(parts[1]); // 周期数量 | |
| 67 | 67 | |
| 68 | 68 | IntervalUnit unit = getIntervalUnit(cycleId); |
| 69 | + long periodDays = convertToDays(y, unit); // 转为固定天数 | |
| 69 | 70 | |
| 70 | 71 | List<PeriodResult> results = new ArrayList<>(); |
| 71 | 72 | LocalDate currentStart = start; |
| 72 | 73 | |
| 73 | 74 | while (!currentStart.isAfter(end)) { |
| 74 | - // 计算当前周期的理论结束日期(包含 y 个单位) | |
| 75 | - LocalDate periodEnd = calculatePeriodEnd(currentStart, y, unit); | |
| 76 | - | |
| 77 | - // 实际段结束 = min(periodEnd, end) | |
| 78 | - LocalDate segEnd = periodEnd.isAfter(end) ? end : periodEnd; | |
| 75 | + // 当前段理论结束 = currentStart + periodDays - 1 | |
| 76 | + LocalDate currentEnd = safePlusDays(currentStart, periodDays - 1); | |
| 77 | + if (currentEnd.isAfter(end)) { | |
| 78 | + currentEnd = end; // 截断 | |
| 79 | + } | |
| 79 | 80 | |
| 80 | - results.add(new PeriodResult(currentStart, segEnd, x)); | |
| 81 | + results.add(new PeriodResult(currentStart, currentEnd, x)); | |
| 81 | 82 | |
| 82 | 83 | // 下一段从当前段结束的第二天开始 |
| 83 | - LocalDate nextStart = segEnd.plusDays(1); | |
| 84 | - | |
| 85 | - // 如果已经超过总结束时间,则终止 | |
| 84 | + LocalDate nextStart = currentEnd.plusDays(1); | |
| 86 | 85 | if (nextStart.isAfter(end)) { |
| 87 | 86 | break; |
| 88 | 87 | } |
| 89 | - | |
| 90 | 88 | currentStart = nextStart; |
| 91 | 89 | } |
| 92 | 90 | |
| ... | ... | @@ -94,62 +92,70 @@ public class TimeIntervalFrequencyUtil { |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | 94 | /** |
| 97 | - * 计算从 start 开始,经过 y 个单位周期后的结束日期(包含) | |
| 95 | + * 将 y 个单位转换为固定天数 | |
| 98 | 96 | */ |
| 99 | - private static LocalDate calculatePeriodEnd(LocalDate start, int y, IntervalUnit unit) { | |
| 97 | + private static long convertToDays(int y, IntervalUnit unit) { | |
| 100 | 98 | switch (unit) { |
| 101 | 99 | case DAY: |
| 102 | - return start.plusDays(y - 1); // 包含 y 天:start 到 start+y-1 | |
| 100 | + return y; | |
| 103 | 101 | case WEEK: |
| 104 | - return start.plusDays((long) y * 7 - 1); // y周 = y*7天,减1得包含结束 | |
| 102 | + return (long) y * 7; | |
| 105 | 103 | case MONTH: |
| 106 | - return addMonthsSafely(start, y).minusDays(1); | |
| 104 | + return (long) y * 30; | |
| 107 | 105 | case YEAR: |
| 108 | - return start.plusYears(y).minusDays(1); | |
| 106 | + return (long) y * 365; | |
| 109 | 107 | default: |
| 110 | - throw new UnsupportedOperationException("未支持的单位: " + unit); | |
| 108 | + throw new UnsupportedOperationException("不支持的单位: " + unit); | |
| 111 | 109 | } |
| 112 | 110 | } |
| 113 | 111 | |
| 114 | - | |
| 115 | - | |
| 116 | 112 | /** |
| 117 | - * 安全地加上 y 个月(避免3月31日+1月变成异常) | |
| 118 | - * 这里使用 Java 8+ 的 plusMonths 自动调整规则 | |
| 113 | + * 安全地加天数(防止溢出) | |
| 119 | 114 | */ |
| 120 | - private static LocalDate addMonthsSafely(LocalDate date, int months) { | |
| 121 | - return date.plusMonths(months); | |
| 122 | - // Java 会自动处理:如 1月31日 +1月 → 2月28/29日(不会抛异常) | |
| 115 | + private static LocalDate safePlusDays(LocalDate date, long days) { | |
| 116 | + if (days == 0) return date; | |
| 117 | + try { | |
| 118 | + return date.plusDays(days); | |
| 119 | + } catch (ArithmeticException e) { | |
| 120 | + return days > 0 ? LocalDate.MAX : LocalDate.MIN; | |
| 121 | + } | |
| 123 | 122 | } |
| 124 | 123 | |
| 125 | - | |
| 126 | - | |
| 127 | - | |
| 128 | 124 | // ====================== 测试用例 ====================== |
| 129 | - //cycleId 1:日/次;2:周/次;3:月/次;4:年/次 | |
| 130 | 125 | public static void main(String[] args) { |
| 131 | - System.out.println("=== 示例1:每3天一次,按日 ==="); | |
| 132 | - List<PeriodResult> r1 = calculate("2025-01-01", "2025-01-07", "1/3", 1); | |
| 126 | + //1:日/次;2:周/次;3:月/次;4:年/次 | |
| 127 | + System.out.println("=== 示例1:每2天3次(即:3/2),按日 ===2025-12-01 2025-12-31"); | |
| 128 | + List<PeriodResult> r1 = calculate("2025-12-01", "2025-12-31", "3/2", 1); | |
| 133 | 129 | r1.forEach(System.out::println); |
| 134 | - | |
| 135 | - System.out.println("\n=== 示例2:每3周一次(21天),按周 ==="); | |
| 136 | - List<PeriodResult> r2 = calculate("2025-01-01", "2025-02-08", "1/2", 2); | |
| 130 | + // 输出: | |
| 131 | + // 2025-01-01 2025-01-03 1次 | |
| 132 | + // 2025-01-04 2025-01-06 1次 | |
| 133 | + // 2025-01-07 2025-01-07 1次 | |
| 134 | + System.out.println("\n=== 示例2:每2周3次(即:3/2)(14天),按周 ===2025-12-01 2025-12-10"); | |
| 135 | + List<PeriodResult> r2 = calculate("2025-12-01", "2025-12-10", "3/2", 2); | |
| 137 | 136 | r2.forEach(System.out::println); |
| 138 | - | |
| 139 | - System.out.println("\n=== 示例3:每5个月一次,按月 ==="); | |
| 140 | - List<PeriodResult> r3 = calculate("2025-11-01", "2025-12-31", "5/1", 3); | |
| 137 | + // 每2周 = 14天 | |
| 138 | + // 2025-01-01 ~ 2025-01-14 | |
| 139 | + // 2025-01-15 ~ 2025-01-28 | |
| 140 | + // 2025-01-29 ~ 2025-02-08(剩余11天) | |
| 141 | + System.out.println("\n=== 示例3:每2个月4次(即:4/2)(30天),按月 === 2025-09-15 2025-12-31"); | |
| 142 | + List<PeriodResult> r3 = calculate("2025-09-15", "2025-12-31", "4/2", 3); | |
| 141 | 143 | r3.forEach(System.out::println); |
| 144 | + // 每1月 = 30天 | |
| 145 | + // 2025-01-01 ~ 2025-01-30 | |
| 146 | + // 2025-01-31 ~ 2025-02-28(30天?→ 实际是29天,但按30天算) | |
| 147 | + // 2025-03-01 ~ 2025-03-15(不足) | |
| 142 | 148 | |
| 143 | - System.out.println("\n=== 示例4:每3年一次,按年 ==="); | |
| 144 | - List<PeriodResult> r4 = calculate("2025-01-01", "2035-06-01", "1/3", 3); | |
| 149 | + System.out.println("\n=== 示例4:每2年1次(即:1/2)(730天),按年 ===2025-01-01 2030-01-01"); | |
| 150 | + List<PeriodResult> r4 = calculate("2025-01-01", "2030-01-01", "1/2", 4); | |
| 145 | 151 | r4.forEach(System.out::println); |
| 146 | - | |
| 147 | - System.out.println("\n=== 示例5:每2天2次,按日 ==="); | |
| 148 | - List<PeriodResult> r5 = calculate("2025-01-01", "2025-01-05", "2/2", 1); | |
| 152 | + // 每2年 = 730天 | |
| 153 | + // 2025-01-01 ~ 2025-12-26(+729d) | |
| 154 | + // 2025-12-27 ~ 2027-12-21 | |
| 155 | + // 2027-12-22 ~ 2029-12-16 | |
| 156 | + // 2029-12-17 ~ 2030-01-01(最后一段) | |
| 157 | + System.out.println("\n=== 示例5:每1年4次(即:4/1),按年(测试)=== 2023-09-15 2025-01-31"); | |
| 158 | + List<PeriodResult> r5 = calculate("2023-09-15", "2025-01-31", "4/1", 4); | |
| 149 | 159 | r5.forEach(System.out::println); |
| 150 | - | |
| 151 | - System.out.println("\n=== 示例5:每2年1次,按年 ==="); | |
| 152 | - List<PeriodResult> r6 = calculate("2025-01-01", "2028-01-05", "1/2", 4); | |
| 153 | - r6.forEach(System.out::println); | |
| 154 | 160 | } |
| 155 | -} | |
| 156 | 161 | \ No newline at end of file |
| 162 | +} | ... | ... |