|
|
|
@ -26,6 +26,7 @@ import java.time.temporal.ChronoUnit; |
|
|
|
import java.time.DayOfWeek; |
|
|
|
import java.time.temporal.TemporalAdjusters; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashSet; |
|
|
|
@ -1107,4 +1108,160 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { |
|
|
|
log.info("[CpPlan-V2] 计划自动匹配预约执行完毕,共匹配{}组联合预约", matchedCount); |
|
|
|
return resultMap; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 计划到期自动生成任务 |
|
|
|
* <p>距计划执行日期 <= CP_SETTING_MANUAL_MATCH_DAYS 天时, |
|
|
|
* 系统自动取消剩余未处理的预约(含系统匹配与手动预约),并为计划生成任务。</p> |
|
|
|
* <ul> |
|
|
|
* <li>部分联合(有已同意的预约):取消剩余待确认预约,已同意的计划共享生成任务</li> |
|
|
|
* <li>完全没有联合记录:直接为计划生成任务</li> |
|
|
|
* <li>全部待确认(无人同意):取消全部待确认预约,为每个计划各自生成任务</li> |
|
|
|
* </ul> |
|
|
|
*/ |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
@Override |
|
|
|
public int processPlanDeadlineAutoGenTask() { |
|
|
|
int manualMatchDays = cpSettingService.getManualMatchDays(); |
|
|
|
LocalDate today = LocalDate.now(); |
|
|
|
LocalDate deadlineDate = today.plusDays(manualMatchDays); |
|
|
|
|
|
|
|
// 1. 查找即将到期的计划:plan_date <= today + manualMatchDays,且未生成任务
|
|
|
|
LambdaQueryWrapper<EfcodeCpPlan> lqw = Wrappers.lambdaQuery(); |
|
|
|
lqw.le(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(deadlineDate)); |
|
|
|
lqw.ge(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(today)); |
|
|
|
lqw.eq(EfcodeCpPlan::getIsDelete, 0L); |
|
|
|
lqw.and(w -> w.isNull(EfcodeCpPlan::getTaskId).or().eq(EfcodeCpPlan::getTaskId, "")); |
|
|
|
lqw.in(EfcodeCpPlan::getReserveStatus, Arrays.asList(1L, 2L, 4L, 5L, 6L)); |
|
|
|
List<EfcodeCpPlan> plans = baseMapper.selectList(lqw); |
|
|
|
|
|
|
|
if (plans.isEmpty()) { |
|
|
|
log.info("[processPlanDeadlineAutoGenTask] 无即将到期的计划需要处理"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
log.info("[processPlanDeadlineAutoGenTask] 找到{}条即将到期的计划(截止日期={})", plans.size(), deadlineDate); |
|
|
|
|
|
|
|
// 2. 查找这些计划的预约记录
|
|
|
|
List<String> planIds = plans.stream().map(EfcodeCpPlan::getId).collect(Collectors.toList()); |
|
|
|
List<EfcodeCpReserve> reserves = efcodeCpReserveMapper.selectList( |
|
|
|
Wrappers.<EfcodeCpReserve>lambdaQuery().in(EfcodeCpReserve::getPlanId, planIds) |
|
|
|
); |
|
|
|
|
|
|
|
// 建立 planId → reserves 映射
|
|
|
|
Map<String, List<EfcodeCpReserve>> planReserveMap = reserves.stream() |
|
|
|
.collect(Collectors.groupingBy(EfcodeCpReserve::getPlanId)); |
|
|
|
|
|
|
|
// 记录已处理的 plan_group_id,避免重复处理同一分组
|
|
|
|
Set<String> processedGroups = new HashSet<>(); |
|
|
|
int processedCount = 0; |
|
|
|
|
|
|
|
for (EfcodeCpPlan plan : plans) { |
|
|
|
// 跳过已经在分组处理中被赋予了 taskId 的计划
|
|
|
|
if (StringUtils.isNotBlank(plan.getTaskId())) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
List<EfcodeCpReserve> planReserves = planReserveMap.get(plan.getId()); |
|
|
|
|
|
|
|
if (planReserves == null || planReserves.isEmpty()) { |
|
|
|
// Case B: 完全没有联合记录 → 直接生成任务
|
|
|
|
log.info("[processPlanDeadlineAutoGenTask] 计划[{}]无联合记录,直接生成任务, 企业={}", |
|
|
|
plan.getId(), plan.getEnterpriseName()); |
|
|
|
cpTaskService.forceGenerateTask(plan); |
|
|
|
processedCount++; |
|
|
|
} else { |
|
|
|
// Case A: 有联合记录 → 按 plan_group_id 处理
|
|
|
|
for (EfcodeCpReserve reserve : planReserves) { |
|
|
|
String groupId = reserve.getPlanGroupId(); |
|
|
|
if (StringUtils.isBlank(groupId) || processedGroups.contains(groupId)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
processedGroups.add(groupId); |
|
|
|
processedCount += processDeadlineGroup(groupId); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
log.info("[processPlanDeadlineAutoGenTask] 处理完毕,共处理{}条计划", processedCount); |
|
|
|
return processedCount; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 处理一个预约分组的截止逻辑: |
|
|
|
* 1. 取消所有待确认(opStatus=3)的预约 → 设为超期取消(4) |
|
|
|
* 2. 为已同意(opStatus=1)的计划生成共享任务 |
|
|
|
* 3. 为被取消的计划各自生成独立任务 |
|
|
|
* |
|
|
|
* @param groupId 预约分组ID |
|
|
|
* @return 处理的计划数量 |
|
|
|
*/ |
|
|
|
private int processDeadlineGroup(String groupId) { |
|
|
|
// 查询分组内所有预约记录
|
|
|
|
List<EfcodeCpReserve> groupReserves = efcodeCpReserveMapper.selectList( |
|
|
|
Wrappers.<EfcodeCpReserve>lambdaQuery().eq(EfcodeCpReserve::getPlanGroupId, groupId) |
|
|
|
); |
|
|
|
if (groupReserves.isEmpty()) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
// 1. 取消所有待确认的预约 (opStatus=3 → 4)
|
|
|
|
List<EfcodeCpReserve> pendingReserves = groupReserves.stream() |
|
|
|
.filter(r -> Long.valueOf(3L).equals(r.getOpStatus())) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
for (EfcodeCpReserve pending : pendingReserves) { |
|
|
|
EfcodeCpReserve update = new EfcodeCpReserve(); |
|
|
|
update.setId(pending.getId()); |
|
|
|
update.setOpStatus(4L); // 超期取消
|
|
|
|
update.setOpTime(new Date()); |
|
|
|
efcodeCpReserveMapper.updateById(update); |
|
|
|
log.info("[processDeadlineGroup] 取消待确认预约: reserveId={}, planId={}, groupId={}", |
|
|
|
pending.getId(), pending.getPlanId(), groupId); |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 找出已同意的预约 (opStatus=1)
|
|
|
|
List<EfcodeCpReserve> approvedReserves = groupReserves.stream() |
|
|
|
.filter(r -> Long.valueOf(1L).equals(r.getOpStatus())) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
int processedCount = 0; |
|
|
|
|
|
|
|
if (!approvedReserves.isEmpty()) { |
|
|
|
// 有部分或全部同意 → 为同意的计划生成共享任务
|
|
|
|
String sharedTaskId = null; |
|
|
|
for (EfcodeCpReserve approved : approvedReserves) { |
|
|
|
EfcodeCpPlan approvedPlan = baseMapper.selectById(approved.getPlanId()); |
|
|
|
if (approvedPlan == null || StringUtils.isNotBlank(approvedPlan.getTaskId())) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (sharedTaskId == null) { |
|
|
|
sharedTaskId = cpTaskService.forceGenerateTask(approvedPlan); |
|
|
|
log.info("[processDeadlineGroup] 已同意计划[{}]生成共享任务taskId={}", |
|
|
|
approvedPlan.getId(), sharedTaskId); |
|
|
|
} else { |
|
|
|
EfcodeCpPlan planUpdate = new EfcodeCpPlan(); |
|
|
|
planUpdate.setId(approvedPlan.getId()); |
|
|
|
planUpdate.setTaskId(sharedTaskId); |
|
|
|
planUpdate.setReserveStatus(3L); |
|
|
|
baseMapper.updateById(planUpdate); |
|
|
|
log.info("[processDeadlineGroup] 已同意计划[{}]加入共享任务taskId={}", |
|
|
|
approvedPlan.getId(), sharedTaskId); |
|
|
|
} |
|
|
|
processedCount++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 为被取消的计划各自生成独立任务
|
|
|
|
for (EfcodeCpReserve pending : pendingReserves) { |
|
|
|
EfcodeCpPlan pendingPlan = baseMapper.selectById(pending.getPlanId()); |
|
|
|
if (pendingPlan == null || StringUtils.isNotBlank(pendingPlan.getTaskId())) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
cpTaskService.forceGenerateTask(pendingPlan); |
|
|
|
log.info("[processDeadlineGroup] 被取消计划[{}]生成独立任务, 企业={}", |
|
|
|
pendingPlan.getId(), pendingPlan.getEnterpriseName()); |
|
|
|
processedCount++; |
|
|
|
} |
|
|
|
|
|
|
|
return processedCount; |
|
|
|
} |
|
|
|
} |
|
|
|
|