This commit is contained in:
Ledo 2025-10-09 00:48:29 +08:00
parent 88529941bf
commit 05383c2355
2 changed files with 247 additions and 281 deletions

View File

@ -315,7 +315,13 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
// 判断请求时间段是否与已有时间段有重叠
boolean hasOverlap = !(reqEnd.compareTo(existStart) < 0) && !(reqStart.compareTo(existEnd) > 0);
if (hasOverlap) {
return CommonResult.error(400, "该子项目设计时间存在交叉,请确认!");
String type="BLUEPRINT_WORKBLANK".equals(updateReqVO.getSubType())?"毛坯":"BLUEPRINT_2D".equals(updateReqVO.getSubType())?"2D":"3D";
String type2="BLUEPRINT_WORKBLANK".equals(planSubDetailDO.getSubType())?"毛坯":"BLUEPRINT_2D".equals(planSubDetailDO.getSubType())?"2D":"3D";
return CommonResult.error(400, "子项目:"+updateReqVO.getName()+" 设计类型:"+type +" "+reqStart.toString().substring(0,10)+" "+reqEnd.toString().substring(0,10)
+""+"子项目:"+planSubDetailDO.getName()+" 设计类型:"+type2 +" "+existStart.toString().substring(0,10)+" "+existEnd.toString().substring(0,10)
+"设计时间存在交叉,请确认!");
}
}
}
@ -424,20 +430,27 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
planSubDetailMapper.updateBatch(list);
//更新表主表数据
//先看有多少个子项目
Map<Long, List<PlanSubDetailDO>> collect = list.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getProjectPlanSubId));
collect.forEach((subId,subList) -> {
Map<Long, List<PlanSubDetailDO>> collect = list.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getProjectSubId));
for (Map.Entry<Long, List<PlanSubDetailDO>> entry : collect.entrySet()) {
Long subId = entry.getKey();
List<PlanSubDetailDO> subList = entry.getValue();
//再根据设计类型来
Map<String, List<PlanSubDetailDO>> collect1 = subList.stream().collect(Collectors.groupingBy(PlanSubDetailDO::getSubType));
//然后对里面的进行排序
collect1.forEach((type,subTypeList) ->{
for (Map.Entry<String, List<PlanSubDetailDO>> entry1 : collect1.entrySet()) {
String type = entry1.getKey();
List<PlanSubDetailDO> subTypeList = entry1.getValue();
List<PlanSubDetailDO> sortedList = subTypeList.stream()
.sorted(Comparator.comparing(PlanSubDetailDO::getSeqNo).reversed())
.collect(Collectors.toList());
Long num = 0L;
for (PlanSubDetailDO planSubDetailDO : sortedList) {
Long designNum = planSubDetailDO.getDesignNum();
num += designNum;
}
LambdaUpdateWrapper<PlanSubDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(PlanSubDO::getProjectSubId,subId);
LocalDateTime startTwoDimDate = sortedList.get(0).getStartTwoDimDate();
LocalDateTime startTwoDimDate = sortedList.get(subTypeList.size()-1).getStartTwoDimDate();
LocalDateTime twoDimDate = sortedList.get(0).getTwoDimDate();
Long num = sortedList.get(0).getDesignNum();
//取最大值就是第一个
if ("BLUEPRINT_WORKBLANK".equals(type)){
lambdaUpdateWrapper.set(PlanSubDO::getStartBlankDate,startTwoDimDate);
@ -453,8 +466,8 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
lambdaUpdateWrapper.set(PlanSubDO::getThreeDimNum,num);
}
planSubMapper.update(lambdaUpdateWrapper);
});
});
}
}
return CommonResult.success(true);
}
@ -523,7 +536,21 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
});
return CommonResult.success(true);
}
/**
* 计算工作天数
*/
private Long calculateWorkDays(LocalDateTime startDate, LocalDateTime endDate) {
long workDays = 0;
LocalDateTime current = startDate.toLocalDate().atStartOfDay();
LocalDateTime end = endDate.toLocalDate().atStartOfDay();
while (!current.isAfter(end)) {
workDays++;
current = current.plusDays(1);
}
return workDays;
}
// @Override
// @Transactional
// public CommonResult chahuoList(PlanSubDetailSaveReqVO updateReqVO) {
@ -987,284 +1014,198 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
List<LocalDateTime> holidayList) {
List<PlanSubDetailDO> resultList = new ArrayList<>();
// 1. 如果没有插活数据直接返回baseList
if (CollUtil.isEmpty(insertList)) {
// 1. 先处理插活数据不按节假日分段保持原始范围
List<PlanSubDetailDO> processedInsertList = new ArrayList<>();
for (PlanSubDetailDO insertItem : insertList) {
// 插活数据保持原始时间范围但designNum排除节假日
PlanSubDetailDO processedItem = new PlanSubDetailDO();
// 复制属性
processedItem.setId(null);
processedItem.setProjectPlanId(insertItem.getProjectPlanId());
processedItem.setProjectId(insertItem.getProjectId());
processedItem.setProjectPlanSubId(insertItem.getProjectPlanSubId());
processedItem.setProjectSubCode(insertItem.getProjectSubCode());
processedItem.setTwoDimOwner(insertItem.getTwoDimOwner());
processedItem.setProjectSubId(insertItem.getProjectPlanSubId());
processedItem.setSubType(insertItem.getSubType());
processedItem.setName(insertItem.getName());
processedItem.setCode(insertItem.getCode());
processedItem.setStartTwoDimDate(insertItem.getStartTwoDimDate());
processedItem.setTwoDimDate(insertItem.getTwoDimDate());
processedItem.setIsCha("Y");
// designNum排除节假日
processedItem.setDesignNum(calculateWorkDaysExcludeHolidays(insertItem.getStartTwoDimDate(), insertItem.getTwoDimDate(), holidayList));
processedInsertList.add(processedItem);
}
// 2. 如果没有插活数据直接返回baseList
if (processedInsertList.isEmpty()) {
return new ArrayList<>(baseList);
}
// 2. 如果baseList为空直接返回所有插活数据
// 3. 处理baseList为空的情况
if (CollUtil.isEmpty(baseList)) {
List<PlanSubDetailDO> processedInsertList = new ArrayList<>();
for (PlanSubDetailDO insertItem : insertList) {
PlanSubDetailDO processedInsert = createInsertItem(insertItem, insertItem.getStartTwoDimDate(), insertItem.getTwoDimDate(), holidayList);
processedInsertList.add(processedInsert);
}
processedInsertList.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
return processedInsertList;
// baseList为空直接返回插活数据
return new ArrayList<>(processedInsertList);
}
// 3. 获取baseList的时间范围
LocalDateTime baseListMinStartTime = baseList.stream()
// 4. 获取插活数据的时间范围
LocalDateTime insertStartTime = processedInsertList.stream()
.map(PlanSubDetailDO::getStartTwoDimDate)
.min(LocalDateTime::compareTo)
.orElse(null);
LocalDateTime baseListMaxEndTime = baseList.stream()
LocalDateTime insertEndTime = processedInsertList.stream()
.map(PlanSubDetailDO::getTwoDimDate)
.max(LocalDateTime::compareTo)
.orElse(null);
// 4. 处理插活数据保持原有时间范围但重新计算designNum排除节假日
List<PlanSubDetailDO> processedInsertList = new ArrayList<>();
for (PlanSubDetailDO insertItem : insertList) {
LocalDateTime startDate = insertItem.getStartTwoDimDate();
LocalDateTime endDate = insertItem.getTwoDimDate();
// 5. 获取baseList的时间范围
LocalDateTime baseMinStartTime = baseList.stream()
.map(PlanSubDetailDO::getStartTwoDimDate)
.min(LocalDateTime::compareTo)
.orElse(null);
LocalDateTime baseMaxEndTime = baseList.stream()
.map(PlanSubDetailDO::getTwoDimDate)
.max(LocalDateTime::compareTo)
.orElse(null);
PlanSubDetailDO processedInsert = createInsertItem(insertItem, startDate, endDate, holidayList);
processedInsertList.add(processedInsert);
// 6. 边界情况处理
if (insertEndTime != null && baseMinStartTime != null && insertEndTime.isBefore(baseMinStartTime)) {
// 情况1插活数据在所有baseList之前
resultList.addAll(processedInsertList);
resultList.addAll(baseList);
return resultList;
}
// 5. 分离插活数据在baseList之前的在baseList之间的在baseList之后的
List<PlanSubDetailDO> beforeBaseListInserts = new ArrayList<>();
List<PlanSubDetailDO> duringBaseListInserts = new ArrayList<>();
List<PlanSubDetailDO> afterBaseListInserts = new ArrayList<>();
if (insertStartTime != null && baseMaxEndTime != null && insertStartTime.isAfter(baseMaxEndTime)) {
// 情况2插活数据在所有baseList之后
resultList.addAll(baseList);
resultList.addAll(processedInsertList);
return resultList;
}
for (PlanSubDetailDO insertItem : processedInsertList) {
if (insertItem.getTwoDimDate().isBefore(baseListMinStartTime)) {
// 插活数据完全在baseList之前
beforeBaseListInserts.add(insertItem);
} else if (insertItem.getStartTwoDimDate().isAfter(baseListMaxEndTime)) {
// 插活数据完全在baseList之后
afterBaseListInserts.add(insertItem);
// 7. 正常插活逻辑插活数据与baseList有重叠
// 分离baseList在插活数据之前的被打断的在插活数据之后的
List<PlanSubDetailDO> beforeInsertList = new ArrayList<>();
List<PlanSubDetailDO> interruptedList = new ArrayList<>();
List<PlanSubDetailDO> afterInsertList = new ArrayList<>();
if (insertStartTime != null) {
for (PlanSubDetailDO baseItem : baseList) {
if (baseItem.getTwoDimDate().isBefore(insertStartTime)) {
// 完全在插活数据之前
beforeInsertList.add(baseItem);
} else if (baseItem.getStartTwoDimDate().isBefore(insertStartTime) &&
baseItem.getTwoDimDate().isAfter(insertStartTime.minusDays(1))) {
// 被插活数据打断
interruptedList.add(baseItem);
} else {
// 在插活数据之后
afterInsertList.add(baseItem);
}
}
} else {
beforeInsertList.addAll(baseList);
}
// 8. 处理插活数据之前的baseList保持原样
resultList.addAll(beforeInsertList);
// 9. 处理被打断的baseList
List<PlanSubDetailDO> remainingBaseList = new ArrayList<>();
for (PlanSubDetailDO interruptedItem : interruptedList) {
// 计算插活数据开始前的天数包含节假日
long daysBeforeInsert = ChronoUnit.DAYS.between(interruptedItem.getStartTwoDimDate(), insertStartTime);
if (daysBeforeInsert > 0) {
// 创建插活前的段落
LocalDateTime segmentEnd = interruptedItem.getStartTwoDimDate().plusDays(daysBeforeInsert - 1);
PlanSubDetailDO beforeSegment = createBaseItem(interruptedItem, interruptedItem.getStartTwoDimDate(), segmentEnd);
// designNum排除节假日
beforeSegment.setDesignNum(calculateWorkDaysExcludeHolidays(interruptedItem.getStartTwoDimDate(), segmentEnd, holidayList));
resultList.add(beforeSegment);
// 保存剩余的designNum原始designNum减去已使用的
Long usedDesignNum = calculateWorkDaysExcludeHolidays(interruptedItem.getStartTwoDimDate(), segmentEnd, holidayList);
Long remainingDesignNum = interruptedItem.getDesignNum() - usedDesignNum;
if (remainingDesignNum > 0) {
// 创建剩余的baseItem稍后处理
PlanSubDetailDO remainingItem = new PlanSubDetailDO();
// 复制属性
remainingItem.setId(interruptedItem.getId());
remainingItem.setProjectPlanId(interruptedItem.getProjectPlanId());
remainingItem.setProjectId(interruptedItem.getProjectId());
remainingItem.setProjectPlanSubId(interruptedItem.getProjectPlanSubId());
remainingItem.setProjectSubCode(interruptedItem.getProjectSubCode());
remainingItem.setTwoDimOwner(interruptedItem.getTwoDimOwner());
remainingItem.setProjectSubId(interruptedItem.getProjectPlanSubId());
remainingItem.setSubType(interruptedItem.getSubType());
remainingItem.setName(interruptedItem.getName());
remainingItem.setCode(interruptedItem.getCode());
remainingItem.setDesignNum(remainingDesignNum);
remainingBaseList.add(remainingItem);
}
} else {
// 插活数据与baseList有重叠或在baseList之间
duringBaseListInserts.add(insertItem);
// 整个被打断全部加入剩余列表
remainingBaseList.add(interruptedItem);
}
}
// 6. 处理在baseList之前的插活数据直接添加到结果列表前面
beforeBaseListInserts.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
resultList.addAll(beforeBaseListInserts);
// 10. 添加插活数据
resultList.addAll(processedInsertList);
// 7. 处理baseList和在其间的插活数据
if (CollUtil.isEmpty(duringBaseListInserts)) {
// 没有在baseList之间的插活数据baseList保持原样
resultList.addAll(baseList);
} else {
// 有在baseList之间的插活数据需要重新编排
// 重新构建结果列表考虑插活数据对多个baseList的影响
resultList.addAll(rebuildListWithInserts(baseList, duringBaseListInserts, holidayList));
// 11. 处理剩余的baseList被打断的剩余部分 + 原本在插活数据之后的
List<PlanSubDetailDO> allRemainingList = new ArrayList<>();
allRemainingList.addAll(remainingBaseList);
allRemainingList.addAll(afterInsertList);
if (!allRemainingList.isEmpty()) {
// 获取插活数据的最后结束时间
LocalDateTime lastInsertEndTime = processedInsertList.stream()
.map(PlanSubDetailDO::getTwoDimDate)
.max(LocalDateTime::compareTo)
.orElse(null);
// 从插活数据的下一天开始顺延
LocalDateTime baseStartTime = lastInsertEndTime.plusDays(1);
for (PlanSubDetailDO baseItem : allRemainingList) {
// 按照原有的designNum计算新的时间段排除节假日
LocalDateTime newStartTime = findNextNonHoliday(baseStartTime, holidayList);
LocalDateTime newEndTime = calculateEndDateByWorkDays(newStartTime, baseItem.getDesignNum(), holidayList);
// 创建新的baseItem
PlanSubDetailDO newBaseItem = createBaseItem(baseItem, newStartTime, newEndTime);
newBaseItem.setDesignNum(baseItem.getDesignNum()); // 保持原始designNum
resultList.add(newBaseItem);
// 更新下一个baseItem的开始时间
baseStartTime = newEndTime.plusDays(1);
}
}
// 8. 处理在baseList之后的插活数据直接添加到baseList后面
afterBaseListInserts.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
resultList.addAll(afterBaseListInserts);
// 9. 按开始时间排序
// 12. 按开始时间排序
resultList.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
return resultList;
}
/**
* 重新构建包含插活数据的列表
*/
private List<PlanSubDetailDO> rebuildListWithInserts(List<PlanSubDetailDO> baseList,
List<PlanSubDetailDO> insertItems,
List<LocalDateTime> holidayList) {
List<PlanSubDetailDO> resultList = new ArrayList<>();
// 按时间排序插活数据
insertItems.sort(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate));
// 处理每个baseList考虑插活数据的影响
for (PlanSubDetailDO baseItem : baseList) {
// 找出与这个baseItem重叠的插活数据
List<PlanSubDetailDO> overlappingInserts = insertItems.stream()
.filter(insert -> !(insert.getTwoDimDate().isBefore(baseItem.getStartTwoDimDate()) ||
insert.getStartTwoDimDate().isAfter(baseItem.getTwoDimDate())))
.sorted(Comparator.comparing(PlanSubDetailDO::getStartTwoDimDate))
.collect(Collectors.toList());
if (overlappingInserts.isEmpty()) {
// 没有重叠的插活数据保持原样
resultList.add(baseItem);
} else {
// 有重叠的插活数据需要分割baseItem
List<PlanSubDetailDO> splitSegments = splitBaseItemByInserts(baseItem, overlappingInserts, holidayList);
resultList.addAll(splitSegments);
}
}
// 添加插活数据
resultList.addAll(insertItems);
return resultList;
}
/**
* 根据插活数据分割baseItem
*/
private List<PlanSubDetailDO> splitBaseItemByInserts(PlanSubDetailDO baseItem,
List<PlanSubDetailDO> overlappingInserts,
List<LocalDateTime> holidayList) {
List<PlanSubDetailDO> segments = new ArrayList<>();
LocalDateTime baseStart = baseItem.getStartTwoDimDate();
LocalDateTime baseEnd = baseItem.getTwoDimDate();
Long originalDesignNum = baseItem.getDesignNum();
// 处理baseItem被插活数据分割的情况
LocalDateTime currentStart = baseStart;
Long usedDesignNum = 0L;
for (PlanSubDetailDO insert : overlappingInserts) {
LocalDateTime insertStart = insert.getStartTwoDimDate();
LocalDateTime insertEnd = insert.getTwoDimDate();
// 如果当前开始时间在插活数据之前创建一个segment
if (currentStart.isBefore(insertStart)) {
// 计算这个时间段内可用的工作日数
Long availableWorkDays = calculateWorkDaysExcludingHolidays(currentStart, insertStart.minusDays(1), holidayList);
Long segmentDesignNum = Math.min(availableWorkDays, originalDesignNum - usedDesignNum);
if (segmentDesignNum > 0) {
// 根据designNum计算实际的结束日期
LocalDateTime segmentEnd = calculateEndDateByDesignNum(currentStart, segmentDesignNum, holidayList);
PlanSubDetailDO segment = createBaseItem(baseItem, currentStart, segmentEnd, holidayList);
segment.setDesignNum(segmentDesignNum);
segments.add(segment);
usedDesignNum += segmentDesignNum;
currentStart = segmentEnd.plusDays(1);
}
}
// 跳过插活数据的时间段
currentStart = insertEnd.plusDays(1);
}
// 处理最后一个插活数据之后的部分
if (usedDesignNum < originalDesignNum) {
Long remainingDesignNum = originalDesignNum - usedDesignNum;
// 从插活数据结束后的下一天开始找到第一个工作日
LocalDateTime segmentStart = findNextWorkDay(currentStart, holidayList);
// 根据剩余的designNum计算结束日期包含节假日但designNum只计算工作日
LocalDateTime segmentEnd = calculateEndDateByDesignNumWithHolidays(segmentStart, remainingDesignNum, holidayList);
PlanSubDetailDO segment = createBaseItem(baseItem, segmentStart, segmentEnd, holidayList);
segment.setDesignNum(remainingDesignNum);
segments.add(segment);
}
return segments;
}
/**
* 根据designNum计算结束日期包含节假日但designNum只计算工作日
*/
private LocalDateTime calculateEndDateByDesignNumWithHolidays(LocalDateTime startDate, Long designNum, List<LocalDateTime> holidayList) {
LocalDateTime current = startDate;
Long workDays = 0L;
while (workDays < designNum) {
if (!isHoliday(current, holidayList)) {
workDays++;
}
if (workDays < designNum) {
current = current.plusDays(1);
}
}
return current;
}
/**
* 根据designNum计算结束日期跳过节假日
*/
private LocalDateTime calculateEndDateByDesignNum(LocalDateTime startDate, Long designNum, List<LocalDateTime> holidayList) {
LocalDateTime current = startDate;
Long workDays = 0L;
while (workDays < designNum) {
if (!isHoliday(current, holidayList)) {
workDays++;
}
if (workDays < designNum) {
current = current.plusDays(1);
}
}
return current;
}
/**
* 创建插活数据项保持原有时间范围排除节假日计算designNum
*/
private PlanSubDetailDO createInsertItem(PlanSubDetailDO original, LocalDateTime startDate, LocalDateTime endDate, List<LocalDateTime> holidayList) {
PlanSubDetailDO insertItem = new PlanSubDetailDO();
copyBaseItemProperties(insertItem, original);
insertItem.setId(null); // 插活数据id为空
insertItem.setIsCha("Y"); // 标记为插活
insertItem.setStartTwoDimDate(startDate);
insertItem.setTwoDimDate(endDate);
// 计算排除节假日的工作天数
insertItem.setDesignNum(calculateWorkDaysExcludingHolidays(startDate, endDate, holidayList));
return insertItem;
}
/**
* 复制baseItem属性
*/
private void copyBaseItemProperties(PlanSubDetailDO target, PlanSubDetailDO source) {
target.setProjectPlanId(source.getProjectPlanId());
target.setProjectId(source.getProjectId());
target.setProjectPlanSubId(source.getProjectPlanSubId());
target.setProjectSubCode(source.getProjectSubCode());
target.setTwoDimOwner(source.getTwoDimOwner());
target.setProjectSubId(source.getProjectSubId());
target.setSubType(source.getSubType());
target.setName(source.getName());
target.setCode(source.getCode());
}
/**
* 查找下一个工作日
*/
private LocalDateTime findNextWorkDay(LocalDateTime date, List<LocalDateTime> holidayList) {
LocalDateTime current = date;
while (isHoliday(current, holidayList)) {
current = current.plusDays(1);
}
return current;
}
/**
* 查找下一个节假日
*/
private LocalDateTime findNextHoliday(LocalDateTime date, List<LocalDateTime> holidayList) {
return holidayList.stream()
.filter(holiday -> !holiday.isBefore(date))
.min(LocalDateTime::compareTo)
.orElse(null);
}
/**
* 检查是否是节假日
*/
private boolean isHoliday(LocalDateTime date, List<LocalDateTime> holidayList) {
return holidayList.contains(date.toLocalDate().atStartOfDay());
}
/**
* 计算排除节假日的工作天数
*/
private Long calculateWorkDaysExcludingHolidays(LocalDateTime startDate, LocalDateTime endDate, List<LocalDateTime> holidayList) {
private Long calculateWorkDaysExcludeHolidays(LocalDateTime startDate, LocalDateTime endDate, List<LocalDateTime> holidayList) {
long workDays = 0;
LocalDateTime current = startDate.toLocalDate().atStartOfDay();
LocalDateTime end = endDate.toLocalDate().atStartOfDay();
while (!current.isAfter(end)) {
if (!isHoliday(current, holidayList)) {
// 检查是否是节假日
LocalDateTime finalCurrent = current;
boolean isHoliday = holidayList.stream()
.anyMatch(holiday -> holiday.isEqual(finalCurrent));
if (!isHoliday) {
workDays++;
}
current = current.plusDays(1);
@ -1273,46 +1214,71 @@ public class PlanSubDetailServiceImpl implements PlanSubDetailService {
return workDays;
}
/**
* 根据工作天数计算结束日期包含节假日
*/
private LocalDateTime calculateEndDateByWorkDays(LocalDateTime startDate, Long workDays, List<LocalDateTime> holidayList) {
LocalDateTime current = startDate;
long countedWorkDays = 0;
while (countedWorkDays < workDays) {
// 检查是否是节假日
LocalDateTime finalCurrent = current;
boolean isHoliday = holidayList.stream()
.anyMatch(holiday -> holiday.isEqual(finalCurrent));
if (!isHoliday) {
countedWorkDays++;
}
if (countedWorkDays < workDays) {
current = current.plusDays(1);
}
}
return current;
}
/**
* 找到下一个非节假日日期
*/
private LocalDateTime findNextNonHoliday(LocalDateTime startDate, List<LocalDateTime> holidayList) {
LocalDateTime current = startDate;
while (true) {
LocalDateTime finalCurrent = current;
boolean isHoliday = holidayList.stream()
.anyMatch(holiday -> holiday.isEqual(finalCurrent));
if (!isHoliday) {
return current;
}
current = current.plusDays(1);
}
}
/**
* 创建baseItem对象用于baseList顺延
*/
private PlanSubDetailDO createBaseItem(PlanSubDetailDO original, LocalDateTime startDate, LocalDateTime endDate, List<LocalDateTime> holidayList) {
private PlanSubDetailDO createBaseItem(PlanSubDetailDO original, LocalDateTime startDate, LocalDateTime endDate) {
PlanSubDetailDO baseItem = new PlanSubDetailDO();
copyBaseItemProperties(baseItem, original);
// 复制原有属性
baseItem.setId(original.getId());
baseItem.setDesignNum(calculateWorkDaysExcludingHolidays(startDate, endDate, holidayList));
baseItem.setProjectPlanId(original.getProjectPlanId());
baseItem.setProjectId(original.getProjectId());
baseItem.setProjectPlanSubId(original.getProjectPlanSubId());
baseItem.setProjectSubCode(original.getProjectSubCode());
baseItem.setTwoDimOwner(original.getTwoDimOwner());
baseItem.setProjectSubId(original.getProjectPlanSubId());
baseItem.setSubType(original.getSubType());
baseItem.setName(original.getName());
baseItem.setCode(original.getCode());
baseItem.setStartTwoDimDate(startDate);
baseItem.setTwoDimDate(endDate);
return baseItem;
}
/**
* 获取时间段内的节假日
*/
private List<LocalDateTime> getHolidaysInRange(LocalDateTime startDate, LocalDateTime endDate,
List<LocalDateTime> holidayList) {
return holidayList.stream()
.filter(holiday -> !holiday.isBefore(startDate) && !holiday.isAfter(endDate))
.sorted()
.collect(Collectors.toList());
}
/**
* 计算工作天数排除节假日
*/
private Long calculateWorkDays(LocalDateTime startDate, LocalDateTime endDate) {
long workDays = 0;
LocalDateTime current = startDate.toLocalDate().atStartOfDay();
LocalDateTime end = endDate.toLocalDate().atStartOfDay();
while (!current.isAfter(end)) {
workDays++;
current = current.plusDays(1);
}
return workDays;
}
@Override

View File

@ -595,7 +595,7 @@ const saveForm = async () => {
} else {
message.error('失败:当前页面无数据可供保存')
}
reload() //
getList()
} catch (error) {
message.error('失败:' + error.message)
} finally {
@ -802,7 +802,7 @@ const handleDelete = async (row) => {
try {
await PlansubdetailApi.deletePlanSubDetail(row.id)
message.success('删除成功')
reload() //
getList() //
} catch (e) {
console.error('删除失败:', e)
}