Commit 9ef9a3d0a8ea581d4673ef152a0fc65ab946f7b9

Authored by 王富生
1 parent 5c63a885

养护计划提交

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,6 +52,14 @@ public class InspectionPlanDetailRespVO {
52 @ExcelProperty("执行时间") 52 @ExcelProperty("执行时间")
53 private LocalDateTime endTime; 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 @Schema(description = "完成状态 1:未完成;2:进行中;3:已完成", requiredMode = Schema.RequiredMode.REQUIRED) 63 @Schema(description = "完成状态 1:未完成;2:进行中;3:已完成", requiredMode = Schema.RequiredMode.REQUIRED)
56 @ExcelProperty("完成状态 1:未完成;2:进行中;3:已完成") 64 @ExcelProperty("完成状态 1:未完成;2:进行中;3:已完成")
57 private Integer finishState; 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,6 +51,10 @@ public class MaintainPlanDetailRespVO {
51 @ExcelProperty("执行时间") 51 @ExcelProperty("执行时间")
52 private LocalDateTime endTime; 52 private LocalDateTime endTime;
53 53
  54 + @Schema(description = "计划次数")
  55 + @ExcelProperty("计划次数")
  56 + private Integer planNum;
  57 +
54 @Schema(description = "完成百分比", requiredMode = Schema.RequiredMode.REQUIRED) 58 @Schema(description = "完成百分比", requiredMode = Schema.RequiredMode.REQUIRED)
55 @ExcelProperty("完成百分比") 59 @ExcelProperty("完成百分比")
56 private Double finishPercent; 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,6 +57,15 @@ public class InspectionPlanDetailDO extends BaseDO {
57 * 排序号:第n次计划 57 * 排序号:第n次计划
58 */ 58 */
59 private Integer sortNum; 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,6 +55,7 @@ public class MaintainPlanDetailDO extends BaseDO {
55 * 排序号:第n次计划 55 * 排序号:第n次计划
56 */ 56 */
57 private Integer sortNum; 57 private Integer sortNum;
  58 +
58 /** 59 /**
59 * 执行开始时间 60 * 执行开始时间
60 */ 61 */
@@ -63,6 +64,12 @@ public class MaintainPlanDetailDO extends BaseDO { @@ -63,6 +64,12 @@ public class MaintainPlanDetailDO extends BaseDO {
63 * 执行时间 64 * 执行时间
64 */ 65 */
65 private LocalDateTime endTime; 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,10 +90,9 @@ public class InspectionPlanServiceImpl implements InspectionPlanService {
90 log.warn("获取两个时间之间间隔天数错误"); 90 log.warn("获取两个时间之间间隔天数错误");
91 return CommonResult.error(INSPECTION_CYCLE_ERROR); 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 //巡检计划list 96 //巡检计划list
98 List<InspectionPlanDO> inspectionPlanList = new ArrayList<>(); 97 List<InspectionPlanDO> inspectionPlanList = new ArrayList<>();
99 //角色列表 98 //角色列表
@@ -138,13 +137,16 @@ public class InspectionPlanServiceImpl implements InspectionPlanService { @@ -138,13 +137,16 @@ public class InspectionPlanServiceImpl implements InspectionPlanService {
138 roleList.add(inspectionPlanRoleDO); 137 roleList.add(inspectionPlanRoleDO);
139 }); 138 });
140 /*3.插入巡查计划明细*/ 139 /*3.插入巡查计划明细*/
  140 + int index = 1;
141 for (PeriodResult periodResult : calculate) { 141 for (PeriodResult periodResult : calculate) {
142 InspectionPlanDetailDO entity = getInspectionPlanDetailDO(batchNo, createReqVO, roadReqVO, now); 142 InspectionPlanDetailDO entity = getInspectionPlanDetailDO(batchNo, createReqVO, roadReqVO, now);
143 ThreadUtil.sleep(2); 143 ThreadUtil.sleep(2);
144 - entity.setSortNum(periodResult.getCount()); 144 + entity.setSortNum(index);
  145 + entity.setPlanNum(periodResult.getCount());
145 entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 146 entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
146 entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 147 entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
147 detailDOList.add(entity); 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,7 +93,7 @@ public class MaintainPlanServiceImpl implements MaintainPlanService {
93 return CommonResult.error(INSPECTION_CYCLE_ERROR); 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 //巡检计划list 97 //巡检计划list
98 List<MaintainPlanDO> maintainPlanList = new ArrayList<>(); 98 List<MaintainPlanDO> maintainPlanList = new ArrayList<>();
99 //角色列表 99 //角色列表
@@ -138,13 +138,16 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { @@ -138,13 +138,16 @@ public class MaintainPlanServiceImpl implements MaintainPlanService {
138 roleList.add(maintainPlanRoleDO); 138 roleList.add(maintainPlanRoleDO);
139 }); 139 });
140 /*3.插入巡查计划明细*/ 140 /*3.插入巡查计划明细*/
  141 + int index =1;
141 for (PeriodResult periodResult : calculate) { 142 for (PeriodResult periodResult : calculate) {
142 MaintainPlanDetailDO entity = getMaintainPlanDetailDO(batchNo, createReqVO, roadReqVO, now); 143 MaintainPlanDetailDO entity = getMaintainPlanDetailDO(batchNo, createReqVO, roadReqVO, now);
143 ThreadUtil.sleep(2); 144 ThreadUtil.sleep(2);
144 - entity.setSortNum(periodResult.getCount()); 145 + entity.setSortNum(index);
  146 + entity.setPlanNum(periodResult.getCount());
145 entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 147 entity.setBeginTime(LocalDateTime.parse(periodResult.getStart() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
146 entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 148 entity.setEndTime(LocalDateTime.parse(periodResult.getEnd() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
147 detailDOList.add(entity); 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,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 public class TimeIntervalFrequencyUtil { 16 public class TimeIntervalFrequencyUtil {
17 17
@@ -42,12 +42,12 @@ public class TimeIntervalFrequencyUtil { @@ -42,12 +42,12 @@ public class TimeIntervalFrequencyUtil {
42 } 42 }
43 43
44 /** 44 /**
45 - * 计算时间段划分结果 45 + * 计算时间段划分结果(基于固定天数换算)
46 * 46 *
47 * @param startStr 开始日期 (yyyy-MM-dd) 47 * @param startStr 开始日期 (yyyy-MM-dd)
48 * @param endStr 结束日期 (yyyy-MM-dd) 48 * @param endStr 结束日期 (yyyy-MM-dd)
49 * @param freq 频次值,格式 "x/y" 49 * @param freq 频次值,格式 "x/y"
50 - * @param cycleId cycleId 1:日/次;2:周/次;3:月/次;4:年/次 50 + * @param cycleId 1:日/次;2:周/次;3:月/次;4:年/次
51 * @return 划分结果列表 51 * @return 划分结果列表
52 */ 52 */
53 public static List<PeriodResult> calculate(String startStr, String endStr, String freq, Integer cycleId) { 53 public static List<PeriodResult> calculate(String startStr, String endStr, String freq, Integer cycleId) {
@@ -62,31 +62,29 @@ public class TimeIntervalFrequencyUtil { @@ -62,31 +62,29 @@ public class TimeIntervalFrequencyUtil {
62 if (parts.length != 2) { 62 if (parts.length != 2) {
63 throw new IllegalArgumentException("频次值格式错误,应为 'x/y': " + freq); 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 IntervalUnit unit = getIntervalUnit(cycleId); 68 IntervalUnit unit = getIntervalUnit(cycleId);
  69 + long periodDays = convertToDays(y, unit); // 转为固定天数
69 70
70 List<PeriodResult> results = new ArrayList<>(); 71 List<PeriodResult> results = new ArrayList<>();
71 LocalDate currentStart = start; 72 LocalDate currentStart = start;
72 73
73 while (!currentStart.isAfter(end)) { 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 if (nextStart.isAfter(end)) { 85 if (nextStart.isAfter(end)) {
87 break; 86 break;
88 } 87 }
89 -  
90 currentStart = nextStart; 88 currentStart = nextStart;
91 } 89 }
92 90
@@ -94,62 +92,70 @@ public class TimeIntervalFrequencyUtil { @@ -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 switch (unit) { 98 switch (unit) {
101 case DAY: 99 case DAY:
102 - return start.plusDays(y - 1); // 包含 y 天:start 到 start+y-1 100 + return y;
103 case WEEK: 101 case WEEK:
104 - return start.plusDays((long) y * 7 - 1); // y周 = y*7天,减1得包含结束 102 + return (long) y * 7;
105 case MONTH: 103 case MONTH:
106 - return addMonthsSafely(start, y).minusDays(1); 104 + return (long) y * 30;
107 case YEAR: 105 case YEAR:
108 - return start.plusYears(y).minusDays(1); 106 + return (long) y * 365;
109 default: 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 public static void main(String[] args) { 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 r1.forEach(System.out::println); 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 r2.forEach(System.out::println); 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 r3.forEach(System.out::println); 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 r4.forEach(System.out::println); 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 r5.forEach(System.out::println); 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 \ No newline at end of file 161 \ No newline at end of file
  162 +}